private static byte[] generate(String name, Class<?> type, Class<?> parameter) {
      name = name.replace('.', '/');

      String typeName = Type.getInternalName(type);
      String typeDesc = Type.getDescriptor(type);
      String parameterName = Type.getInternalName(parameter);
      String parameterDesc = Type.getDescriptor(parameter);

      String constructSignature = '(' + parameterDesc + ')' + typeDesc;

      ClassWriter cw = new ClassWriter(0);
      MethodVisitor mv;

      cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, BASE_CLASS, null);

      {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Class;)V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "<init>", "(Ljava/lang/Class;)V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
      }
      {
        mv = cw.visitMethod(ACC_PUBLIC, "construct", constructSignature, null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, typeName);
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, typeName, "<init>", '(' + parameterDesc + ")V", false);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(3, 2);
        mv.visitEnd();
      }
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
                "construct",
                "(Ljava/lang/Object;)Ljava/lang/Object;",
                null,
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, parameterName);
        mv.visitMethodInsn(INVOKEVIRTUAL, name, "construct", constructSignature, false);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
      }
      cw.visitEnd();

      return cw.toByteArray();
    }
Example #2
0
  public Class<?> createWrapper(Method callback) {
    ClassWriter cw = new ClassWriter(0);
    MethodVisitor mv;

    String name = getUniqueName(callback);
    String desc = name.replace('.', '/');
    String instType = Type.getInternalName(callback.getDeclaringClass());
    String eventType = Type.getInternalName(callback.getParameterTypes()[0]);

    /*
    System.out.println("Name:     " + name);
    System.out.println("Desc:     " + desc);
    System.out.println("InstType: " + instType);
    System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback));
    System.out.println("Event:    " + eventType);
    */

    cw.visit(
        V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC});

    cw.visitSource(".dynamic", null);
    {
      cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd();
    }
    {
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;");
      mv.visitInsn(RETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    {
      mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;");
      mv.visitTypeInsn(CHECKCAST, instType);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, eventType);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback));
      mv.visitInsn(RETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    cw.visitEnd();
    return LOADER.define(name, cw.toByteArray());
  }
 private void declareClass(
     ClassVisitor visitor,
     Collection<String> interfaceInternalNames,
     Type generatedType,
     Type superclassType) {
   visitor.visit(
       V1_6,
       ACC_PUBLIC,
       generatedType.getInternalName(),
       null,
       superclassType.getInternalName(),
       Iterables.toArray(interfaceInternalNames, String.class));
 }
  // 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);
  }
Example #5
0
  @Override
  public Type emit_const(MethodVisitor fa) {
    Type type = ELIST_TYPE;

    fa.visitTypeInsn(Opcodes.NEW, type.getInternalName());
    fa.visitInsn(Opcodes.DUP);

    ((EObject) head).emit_const(fa);
    ((EObject) tail).emit_const(fa);

    fa.visitMethodInsn(Opcodes.INVOKESPECIAL, type.getInternalName(), "<init>", CONSTRUCTOR_DESC);

    return type;
  }
  @Override
  protected void insertTransform(
      MethodVisitor mv, Parameter param, Class<?> targetType, int local) {
    mv.visitVarInsn(ALOAD, local);
    Label failure = new Label();
    Label success = new Label();

    mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "isPresent", "()Z", false);
    mv.visitJumpInsn(IFEQ, failure);

    // Unwrap the optional
    mv.visitVarInsn(ALOAD, local);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "get", "()Ljava/lang/Object;", false);
    mv.visitVarInsn(ASTORE, local);

    mv.visitVarInsn(ALOAD, local);

    mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(targetType));

    if (this.anno.typeFilter().length != 0) {
      mv.visitJumpInsn(IFEQ, failure);
      mv.visitVarInsn(ALOAD, local);
      // For each type we do an instance check and jump to either failure or success if matched
      for (int i = 0; i < this.anno.typeFilter().length; i++) {
        Class<?> filter = this.anno.typeFilter()[i];
        if (i < this.anno.typeFilter().length - 1) {
          mv.visitInsn(DUP);
        }
        mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(filter));
        if (this.anno.inverse()) {
          mv.visitJumpInsn(IFNE, failure);
        } else {
          mv.visitJumpInsn(IFNE, success);
        }
      }
      if (this.anno.inverse()) {
        mv.visitJumpInsn(GOTO, success);
      }
      // If the annotation was not reversed then we fall into failure as no types were matched
    } else {
      mv.visitJumpInsn(IFNE, success);
    }
    mv.visitLabel(failure);
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);

    mv.visitLabel(success);
  }
Example #7
0
  private boolean classIsDefinitelyMutable(ClassNode klass) {
    if (superClassIsDefinitelyMutable(klass.superName)) {
      log.add("Mutable parent: " + klass.name + " < " + klass.superName);
      return true;
    }

    for (FieldNode field : klass.fields) {
      if ((field.access & Opcodes.ACC_STATIC) != 0) {
        continue;
      }
      if ((field.access & Opcodes.ACC_FINAL) == 0) {
        log.add("Non-final field: " + klass.name + "#" + field.name + ":" + field.desc);
        return true;
      }
      if (field.name.contains("$")) {
        // Generated fields are assumed to be effectively immutable.
        // This could, in principle, miss an issue like a static reference to a
        // seemingly-immutable inner class object that maintains a hidden reference
        // to its mutable outer object, but that seems unlikely.
        continue;
      }

      Type type = Type.getType(field.desc);

      if (IMMUTABLE_TYPE_SORTS.contains(type.getSort())) {
        continue;
      }

      if (type.getSort() != Type.OBJECT) {
        log.add("Odd sort: " + klass.name + "#" + field.name + ":" + field.desc);
        return true;
      }

      if (allClasses.keySet().contains(type.getInternalName())) {
        if (classesWithMutableDescendents.contains(type.getInternalName())) {
          log.add("Internal mutable field: " + klass.name + "#" + field.name + ":" + field.desc);
          return true;
        }
      } else {
        if (!EXTERNAL_IMMUTABLE_CLASSES.contains(type.getInternalName())) {
          log.add("External mutable field: " + klass.name + "#" + field.name + ":" + field.desc);
          return true;
        }
      }
    }

    return false;
  }
Example #8
0
 public static Class<?> getClassForType(Type type) {
   checkArgNotNull(type, "type");
   switch (type.getSort()) {
     case Type.BOOLEAN:
       return boolean.class;
     case Type.BYTE:
       return byte.class;
     case Type.CHAR:
       return char.class;
     case Type.DOUBLE:
       return double.class;
     case Type.FLOAT:
       return float.class;
     case Type.INT:
       return int.class;
     case Type.LONG:
       return long.class;
     case Type.SHORT:
       return short.class;
     case Type.VOID:
       return void.class;
     case Type.OBJECT:
     case Type.ARRAY:
       return getClassForInternalName(type.getInternalName());
   }
   throw new IllegalStateException(); // should be unreachable
 }
Example #9
0
  private void generateAccessor(
      ClassWriter cw,
      Class<?> parentType,
      String internalName,
      Property<Class<?>, Method> property) {
    Method accessor = property.getAccessor();

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC, accessor.getName(), Type.getMethodDescriptor(accessor), null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(
        GETFIELD,
        internalName,
        property.getName(),
        Type.getDescriptor(property.getLeastSpecificType()));

    if (!property.isLeastSpecificType()) {
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(property.getType()));
    }
    mv.visitInsn(Type.getType(property.getType()).getOpcode(IRETURN));
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
Example #10
0
 /**
  * Insert the necessary methods to unbox a primitive type (if the given type is a primitive).
  *
  * @param mv The method visitor
  * @param type The type to unbox
  */
 public static void visitUnboxingMethod(MethodVisitor mv, Type type) {
   if (type.getSort() == Type.BOOLEAN) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
   } else if (type.getSort() == Type.INT) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
   } else if (type.getSort() == Type.BYTE) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
   } else if (type.getSort() == Type.SHORT) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
   } else if (type.getSort() == Type.LONG) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
   } else if (type.getSort() == Type.FLOAT) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
   } else if (type.getSort() == Type.DOUBLE) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
   } else if (type.getSort() == Type.CHAR) {
     mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
   } else {
     mv.visitTypeInsn(CHECKCAST, type.getInternalName());
   }
 }
 private void castFirstStackElement(MethodVisitor methodVisitor, Class<?> returnType) {
   if (returnType.isPrimitive()) {
     unboxType(methodVisitor, returnType);
   } else {
     methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(returnType));
   }
 }
 @Override
 public DataType visitPrint_stmt(@NotNull PythonParser.Print_stmtContext ctx) {
   mv.visitFieldInsn(
       GETSTATIC,
       Type.getInternalName(System.class),
       "out",
       Type.getDescriptor(PrintStream.class));
   DataType type = visitTest(ctx.test());
   mv.visitMethodInsn(
       INVOKEVIRTUAL,
       Type.getInternalName(PrintStream.class),
       "println",
       Type.getMethodDescriptor(Type.VOID_TYPE, type.getType()),
       false);
   return null;
 }
    public void addSetMethod(MetaBeanProperty property) throws Exception {
      MetaMethod setter = property.getSetter();
      Type paramType = Type.getType(setter.getParameterTypes()[0].getTheClass());
      Type returnType = Type.getType(setter.getReturnType());
      String setterDescriptor = Type.getMethodDescriptor(returnType, new Type[] {paramType});

      // GENERATE public void <propName>(<type> v) { <setter>(v) }
      String setMethodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {paramType});
      MethodVisitor methodVisitor =
          visitor.visitMethod(
              Opcodes.ACC_PUBLIC, property.getName(), setMethodDescriptor, null, new String[0]);
      methodVisitor.visitCode();

      // GENERATE <setter>(v)

      methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
      methodVisitor.visitVarInsn(paramType.getOpcode(Opcodes.ILOAD), 1);

      methodVisitor.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL,
          generatedType.getInternalName(),
          setter.getName(),
          setterDescriptor);

      // END

      methodVisitor.visitInsn(Opcodes.RETURN);
      methodVisitor.visitMaxs(0, 0);
      methodVisitor.visitEnd();
    }
  private int firePeacefulRegenEventAndStoreEventBefore(
      MethodNode method, AbstractInsnNode injectPoint, LabelNode endLabel) {
    // create  variable
    LabelNode peacefulRegenEventStart = new LabelNode();
    LocalVariableNode peacefulRegenEvent =
        new LocalVariableNode(
            "peacefulRegenEvent",
            Type.getDescriptor(HealthRegenEvent.PeacefulRegen.class),
            null,
            peacefulRegenEventStart,
            endLabel,
            method.maxLocals);
    method.maxLocals += 1;
    method.localVariables.add(peacefulRegenEvent);

    InsnList toInject = new InsnList();

    // HealthRegenEvent.PeacefulRegen peacefulRegenEvent = Hooks.firePeacefulRegenEvent(this);
    toInject.add(new VarInsnNode(ALOAD, 0));
    toInject.add(
        new MethodInsnNode(
            INVOKESTATIC,
            Type.getInternalName(Hooks.class),
            "firePeacefulRegenEvent",
            "(Lnet/minecraft/entity/player/EntityPlayer;)Lsqueek/applecore/api/hunger/HealthRegenEvent$PeacefulRegen;",
            false));
    toInject.add(new VarInsnNode(ASTORE, peacefulRegenEvent.index));
    toInject.add(peacefulRegenEventStart);

    method.instructions.insertBefore(injectPoint, toInject);

    return peacefulRegenEvent.index;
  }
 /**
  * Creates a new local variable of the given type.
  *
  * @param type the type of the local variable to be created.
  * @return the identifier of the newly created local variable.
  */
 public int newLocal(final Type type) {
   Object t;
   switch (type.getSort()) {
     case Type.BOOLEAN:
     case Type.CHAR:
     case Type.BYTE:
     case Type.SHORT:
     case Type.INT:
       t = Opcodes.INTEGER;
       break;
     case Type.FLOAT:
       t = Opcodes.FLOAT;
       break;
     case Type.LONG:
       t = Opcodes.LONG;
       break;
     case Type.DOUBLE:
       t = Opcodes.DOUBLE;
       break;
     case Type.ARRAY:
       t = type.getDescriptor();
       break;
       // case Type.OBJECT:
     default:
       t = type.getInternalName();
       break;
   }
   int local = newLocalMapping(type);
   setLocalType(local, type);
   setFrameLocal(local, t);
   return local;
 }
Example #16
0
  private Type getMirrorType(final Type type) {
    int numDimensions = 0;
    final Type basicType;

    if (type.getSort() == Type.ARRAY) {
      numDimensions = type.getDimensions();
      basicType = type.getElementType();
    } else {
      basicType = type;
    }

    if (basicType.getSort() != Type.OBJECT) {
      return type;
    }

    final Mirror mirror = getMirror(basicType.getInternalName());

    if (mirror.isClassMirror()) {
      final StringBuilder name = new StringBuilder();

      for (int i = 0; i < numDimensions; ++i) {
        name.append('[');
      }
      name.append('L').append(mirror.getTranslatedName()).append(';');

      return Type.getType(name.toString());
    }

    return type;
  }
 private static byte[] generateEventExecutor(Method m, String name) {
   final boolean staticMethod = Modifier.isStatic(m.getModifiers());
   ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
   writer.visit(
       V1_8,
       ACC_PUBLIC,
       name,
       null,
       "java/lang/Object",
       new String[] {Type.getInternalName(EventExecutor.class)});
   // Generate constructor
   MethodVisitor methodGenerator = writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
   methodGenerator.visitVarInsn(ALOAD, 0);
   methodGenerator.visitMethodInsn(
       INVOKESPECIAL,
       "java/lang/Object",
       "<init>",
       "()V",
       false); // Invoke the super class (Object) constructor
   methodGenerator.visitInsn(RETURN);
   methodGenerator.visitMaxs(1, 1);
   methodGenerator.visitEnd();
   // Generate the execute method
   methodGenerator =
       writer.visitMethod(
           ACC_PUBLIC, "fire", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null);
   if (!staticMethod) {
     methodGenerator.visitVarInsn(ALOAD, 1);
     methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getDeclaringClass()));
   }
   methodGenerator.visitVarInsn(ALOAD, 2);
   methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getParameterTypes()[0]));
   methodGenerator.visitMethodInsn(
       staticMethod ? INVOKESTATIC : INVOKEVIRTUAL,
       Type.getInternalName(m.getDeclaringClass()),
       m.getName(),
       Type.getMethodDescriptor(m),
       m.getDeclaringClass().isInterface());
   if (m.getReturnType() != void.class) {
     methodGenerator.visitInsn(POP);
   }
   methodGenerator.visitInsn(RETURN);
   methodGenerator.visitMaxs(staticMethod ? 1 : 2, 3);
   methodGenerator.visitEnd();
   writer.visitEnd();
   return writer.toByteArray();
 }
 private void invokeSuperConstructor(MethodVisitor constructorVisitor, Type superclassType) {
   putThisOnStack(constructorVisitor);
   constructorVisitor.visitMethodInsn(
       INVOKESPECIAL,
       superclassType.getInternalName(),
       CONSTRUCTOR_NAME,
       Type.getMethodDescriptor(Type.VOID_TYPE),
       false);
 }
Example #19
0
 @Override
 public void visitLdcInsn(Object cst) {
   if (cst instanceof Type) {
     Type type = (Type) cst;
     AsmClass usedClass = asmClassProvider.getClass(type.getInternalName(), DETAIL_LEVEL.NOTHING);
     method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber));
   }
   emptyMethod = false;
 }
 private void boxType(MethodVisitor methodVisitor, Class<?> primitiveType) {
   Class<?> boxedType = BOXED_TYPES.get(primitiveType);
   methodVisitor.visitMethodInsn(
       INVOKESTATIC,
       Type.getInternalName(boxedType),
       "valueOf",
       "(" + Type.getDescriptor(primitiveType) + ")" + Type.getDescriptor(boxedType),
       false);
 }
 private void assignStateField(MethodVisitor constructorVisitor, Type generatedType) {
   putThisOnStack(constructorVisitor);
   putFirstMethodArgumentOnStack(constructorVisitor);
   constructorVisitor.visitFieldInsn(
       PUTFIELD,
       generatedType.getInternalName(),
       STATE_FIELD_NAME,
       MODEL_ELEMENT_STATE_TYPE.getDescriptor());
 }
 private void assignTypeConverterField(MethodVisitor constructorVisitor, Type generatedType) {
   putThisOnStack(constructorVisitor);
   putSecondMethodArgumentOnStack(constructorVisitor);
   constructorVisitor.visitFieldInsn(
       PUTFIELD,
       generatedType.getInternalName(),
       TYPE_CONVERTER_FIELD_NAME,
       TYPE_CONVERTER_TYPE.getDescriptor());
 }
 private void invokeSuperMethod(MethodVisitor methodVisitor, Class<?> superClass, Method method) {
   putThisOnStack(methodVisitor);
   methodVisitor.visitMethodInsn(
       INVOKESPECIAL,
       Type.getInternalName(superClass),
       method.getName(),
       Type.getMethodDescriptor(method),
       false);
 }
 @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 assignDelegateField(
     MethodVisitor constructorVisitor, Type generatedType, Type delegateType) {
   putThisOnStack(constructorVisitor);
   putThirdMethodArgumentOnStack(constructorVisitor);
   constructorVisitor.visitFieldInsn(
       PUTFIELD,
       generatedType.getInternalName(),
       DELEGATE_FIELD_NAME,
       delegateType.getDescriptor());
 }
    public void addSetter(MetaBeanProperty property) throws Exception {
      MetaMethod setter = property.getSetter();

      // GENERATE public <return-type> <setter>(<type> v) { <return-type> v = super.<setter>(v);
      // <prop>Set = true; return v; }

      Type paramType = Type.getType(setter.getParameterTypes()[0].getTheClass());
      Type returnType = Type.getType(setter.getReturnType());
      String setterDescriptor = Type.getMethodDescriptor(returnType, new Type[] {paramType});
      MethodVisitor methodVisitor =
          visitor.visitMethod(
              Opcodes.ACC_PUBLIC, setter.getName(), setterDescriptor, null, new String[0]);
      methodVisitor.visitCode();

      // GENERATE super.<setter>(v)

      methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
      methodVisitor.visitVarInsn(paramType.getOpcode(Opcodes.ILOAD), 1);

      methodVisitor.visitMethodInsn(
          Opcodes.INVOKESPECIAL,
          superclassType.getInternalName(),
          setter.getName(),
          setterDescriptor);

      // END

      // GENERATE <prop>Set = true

      methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
      methodVisitor.visitLdcInsn(true);
      methodVisitor.visitFieldInsn(
          Opcodes.PUTFIELD,
          generatedType.getInternalName(),
          String.format("%sSet", property.getName()),
          Type.BOOLEAN_TYPE.getDescriptor());

      // END

      methodVisitor.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
      methodVisitor.visitMaxs(0, 0);
      methodVisitor.visitEnd();
    }
 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());
 }
 private void addType(Type t) {
   switch (t.getSort()) {
     case Type.ARRAY:
       addType(t.getElementType());
       break;
     case Type.OBJECT:
       addName(t.getInternalName());
       break;
   }
 }
Example #29
0
  /**
   * Create the event class.
   *
   * @param type The type
   * @param name The canonical of the generated class
   * @param parentType The parent type
   * @return The class' contents, to be loaded via a {@link ClassLoader}
   */
  public byte[] createClass(
      final Class<?> type,
      final String name,
      final Class<?> parentType,
      List<? extends EventFactoryPlugin> plugins) {
    checkNotNull(type, "type");
    checkNotNull(name, "name");
    checkNotNull(parentType, "parentType");

    final ImmutableSet<? extends Property<Class<?>, Method>> properties =
        this.propertySearch.findProperties(new ReflectionClassWrapper(type));
    final String internalName = getInternalName(name);

    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    cw.visit(
        V1_6,
        ACC_PUBLIC + ACC_SUPER,
        internalName,
        null,
        Type.getInternalName(parentType),
        new String[] {Type.getInternalName(type)});

    MethodVisitor toStringMv = this.initializeToString(cw, type);

    this.generateWithPlugins(cw, type, parentType, internalName, properties, toStringMv, plugins);

    // Create the fields
    // this.contributeFields(cw, parentType, properties, plugins);

    // Create the constructor
    this.generateConstructor(cw, internalName, parentType, properties);

    // The return value of toString takes the form of
    // "ClassName{param1=value1, param2=value2, ...}"

    // Create the accessors and mutators, and fill out the toString method

    this.finalizeToString(toStringMv);

    cw.visitEnd();

    return cw.toByteArray();
  }
  public void addPeacefulRegenHook(ClassNode classNode, MethodNode method) {
    AbstractInsnNode relevantConditional =
        ASMHelper.find(method.instructions, new LdcInsnNode("naturalRegeneration"));
    JumpInsnNode ifNode =
        (JumpInsnNode) ASMHelper.find(relevantConditional, new JumpInsnNode(IFEQ, new LabelNode()));
    LabelNode ifBlockEndLabel = ifNode.label;
    AbstractInsnNode targetNode = ASMHelper.find(ifNode, new InsnNode(FCONST_1)).getPrevious();

    int peacefulRegenEventIndex =
        firePeacefulRegenEventAndStoreEventBefore(method, targetNode, ifBlockEndLabel);

    InsnList healAmountNeedle = new InsnList();
    healAmountNeedle.add(new InsnNode(FCONST_1));

    InsnList healAmountReplacement = new InsnList();
    healAmountReplacement.add(new VarInsnNode(ALOAD, peacefulRegenEventIndex));
    healAmountReplacement.add(
        new FieldInsnNode(
            GETFIELD,
            Type.getInternalName(HealthRegenEvent.PeacefulRegen.class),
            "deltaHealth",
            "F"));

    ASMHelper.findAndReplace(
        method.instructions, healAmountNeedle, healAmountReplacement, targetNode);

    InsnList ifNotCanceledBlock = new InsnList();
    LabelNode ifNotCanceled = new LabelNode();

    ifNotCanceledBlock.add(new VarInsnNode(ALOAD, peacefulRegenEventIndex));
    ifNotCanceledBlock.add(
        new MethodInsnNode(
            INVOKEVIRTUAL,
            Type.getInternalName(HealthRegenEvent.PeacefulRegen.class),
            "isCanceled",
            "()Z",
            false));
    ifNotCanceledBlock.add(new JumpInsnNode(IFNE, ifNotCanceled));
    method.instructions.insertBefore(targetNode, ifNotCanceledBlock);

    method.instructions.insertBefore(ifBlockEndLabel, ifNotCanceled);
  }