/**
  * ensure last marked parameter on the stack is a primitive boolean if mark==stack size, we assume
  * an empty expression or statement. was used and we will use the value given in emptyDefault as
  * boolean if mark==stack.size()-1 the top element will be cast to boolean using Groovy truth. In
  * other cases we throw a GroovyBugError
  */
 public void castToBool(int mark, boolean emptyDefault) {
   int size = stack.size();
   MethodVisitor mv = controller.getMethodVisitor();
   if (mark == size) {
     // no element, so use emptyDefault
     if (emptyDefault) {
       mv.visitIntInsn(BIPUSH, 1);
     } else {
       mv.visitIntInsn(BIPUSH, 0);
     }
     stack.add(null);
   } else if (mark == stack.size() - 1) {
     ClassNode last = stack.get(size - 1);
     // nothing to do in that case
     if (last == ClassHelper.boolean_TYPE) return;
     // not a primitive type, so call booleanUnbox
     if (!ClassHelper.isPrimitiveType(last)) {
       controller.getInvocationWriter().castNonPrimitiveToBool(last);
     } else {
       primitive2b(mv, last);
     }
   } else {
     throw new GroovyBugError(
         "operand stack contains " + stack.size() + " elements, but we expected only " + mark);
   }
   stack.set(mark, ClassHelper.boolean_TYPE);
 }
 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 initializeDelegateObject(final MethodVisitor mv, int argStart) {
   int idx = argStart + 1;
   mv.visitIntInsn(ALOAD, 0); // this
   mv.visitIntInsn(ALOAD, idx); // constructor arg n is the closure map
   mv.visitFieldInsn(
       PUTFIELD,
       proxyName,
       DELEGATE_OBJECT_FIELD,
       BytecodeHelper.getTypeDescription(delegateClass));
 }
  /** 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;
  }
Example #5
0
  /** Generates the bytecode that pushes the given value onto the stack */
  public void pushInt(int aValue) {
    switch (aValue) {
      case -1:
        itsVisitor.visitInsn(Opcodes.ICONST_M1);
        return;

      case 0:
        itsVisitor.visitInsn(Opcodes.ICONST_0);
        return;

      case 1:
        itsVisitor.visitInsn(Opcodes.ICONST_1);
        return;

      case 2:
        itsVisitor.visitInsn(Opcodes.ICONST_2);
        return;

      case 3:
        itsVisitor.visitInsn(Opcodes.ICONST_3);
        return;

      case 4:
        itsVisitor.visitInsn(Opcodes.ICONST_4);
        return;

      case 5:
        itsVisitor.visitInsn(Opcodes.ICONST_5);
        return;
    }

    if (aValue >= Byte.MIN_VALUE && aValue <= Byte.MAX_VALUE)
      itsVisitor.visitIntInsn(Opcodes.BIPUSH, aValue);
    else if (aValue >= Short.MIN_VALUE && aValue <= Short.MAX_VALUE)
      itsVisitor.visitIntInsn(Opcodes.SIPUSH, aValue);
    else itsVisitor.visitLdcInsn(new Integer(aValue));
  }
 private MethodVisitor createConstructor(
     final int access,
     final String name,
     final String desc,
     final String signature,
     final String[] exceptions) {
   Type[] args = Type.getArgumentTypes(desc);
   StringBuilder newDesc = new StringBuilder("(");
   for (Type arg : args) {
     newDesc.append(arg.getDescriptor());
   }
   newDesc.append("Ljava/util/Map;"); // the closure map
   if (generateDelegateField) {
     newDesc.append(BytecodeHelper.getTypeDescription(delegateClass));
   }
   newDesc.append(")V");
   MethodVisitor mv = super.visitMethod(access, name, newDesc.toString(), signature, exceptions);
   mv.visitCode();
   initializeDelegateClosure(mv, args.length);
   if (generateDelegateField) {
     initializeDelegateObject(mv, args.length + 1);
   }
   mv.visitVarInsn(ALOAD, 0);
   int idx = 1;
   for (Type arg : args) {
     if (isPrimitive(arg)) {
       mv.visitIntInsn(getLoadInsn(arg), idx);
     } else {
       mv.visitVarInsn(ALOAD, idx); // load argument i
     }
     idx += registerLen(arg);
   }
   mv.visitMethodInsn(
       INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", desc);
   mv.visitInsn(RETURN);
   int max = idx + 1 + (generateDelegateField ? 1 : 0);
   mv.visitMaxs(max, max);
   mv.visitEnd();
   return EMPTY_VISITOR;
 }
 @Override
 public void visitIntInsn(final int opcode, final int operand) {
   checkStartCode();
   checkEndCode();
   checkOpcode(opcode, 1);
   switch (opcode) {
     case Opcodes.BIPUSH:
       checkSignedByte(operand, "Invalid operand");
       break;
     case Opcodes.SIPUSH:
       checkSignedShort(operand, "Invalid operand");
       break;
       // case Constants.NEWARRAY:
     default:
       if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
         throw new IllegalArgumentException(
             "Invalid operand (must be an array type code T_...): " + operand);
       }
   }
   super.visitIntInsn(opcode, operand);
   ++insnCount;
 }
 private void initializeDelegateClosure(final MethodVisitor mv, int argStart) {
   int idx = argStart + 1;
   mv.visitIntInsn(ALOAD, 0); // this
   mv.visitIntInsn(ALOAD, idx); // constructor arg n is the closure map
   mv.visitFieldInsn(PUTFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;");
 }
  /**
   * When an object doesn't implement the GroovyObject interface, we generate bytecode for the
   * {@link GroovyObject} interface methods. Otherwise, the superclass is expected to implement
   * them.
   */
  private void createGroovyObjectSupport() {
    visitField(ACC_PRIVATE + ACC_TRANSIENT, "metaClass", "Lgroovy/lang/MetaClass;", null, null);

    // getMetaClass
    MethodVisitor mv;
    {
      mv = super.visitMethod(ACC_PUBLIC, "getMetaClass", "()Lgroovy/lang/MetaClass;", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;");
      Label l1 = new Label();
      mv.visitJumpInsn(IFNONNULL, l1);
      Label l2 = new Label();
      mv.visitLabel(l2);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
      mv.visitMethodInsn(
          INVOKESTATIC,
          "org/codehaus/groovy/runtime/InvokerHelper",
          "getMetaClass",
          "(Ljava/lang/Class;)Lgroovy/lang/MetaClass;");
      mv.visitFieldInsn(PUTFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;");
      mv.visitLabel(l1);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;");
      mv.visitInsn(ARETURN);
      mv.visitMaxs(2, 1);
      mv.visitEnd();
    }

    // getProperty
    {
      mv =
          super.visitMethod(
              ACC_PUBLIC, "getProperty", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
      mv.visitCode();
      mv.visitIntInsn(ALOAD, 0);
      mv.visitMethodInsn(
          INVOKEINTERFACE, "groovy/lang/GroovyObject", "getMetaClass", "()Lgroovy/lang/MetaClass;");
      mv.visitIntInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          "groovy/lang/MetaClass",
          "getProperty",
          "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");
      mv.visitInsn(ARETURN);
      mv.visitMaxs(3, 2);
      mv.visitEnd();
    }

    // setProperty
    {
      mv =
          super.visitMethod(
              ACC_PUBLIC, "setProperty", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKEVIRTUAL, proxyName, "getMetaClass", "()Lgroovy/lang/MetaClass;");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          "groovy/lang/MetaClass",
          "setProperty",
          "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitInsn(RETURN);
      Label l2 = new Label();
      mv.visitLabel(l2);
      mv.visitMaxs(4, 3);
      mv.visitEnd();
    }

    // invokeMethod
    {
      mv =
          super.visitMethod(
              ACC_PUBLIC,
              "invokeMethod",
              "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;",
              null,
              null);
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKEVIRTUAL, proxyName, "getMetaClass", "()Lgroovy/lang/MetaClass;");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          "groovy/lang/MetaClass",
          "invokeMethod",
          "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
      mv.visitInsn(ARETURN);
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitMaxs(4, 3);
      mv.visitEnd();
    }

    // setMetaClass
    {
      mv = super.visitMethod(ACC_PUBLIC, "setMetaClass", "(Lgroovy/lang/MetaClass;)V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;");
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitInsn(RETURN);
      Label l2 = new Label();
      mv.visitLabel(l2);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
  }
 public void visitIntInsn(int i, int i1) {
   System.out.println("visitIntInsn(" + opcodeAsString(i) + ", " + i1 + ")");
   methodVisitor.visitIntInsn(i, i1);
 }
Example #11
0
  @Override
  public void compile(Type type, MethodVisitor mv, AsmDeserializerContext context) {

    mv.visitCode();

    //      if (flag == Types.NULL) {
    //   		return null;
    //  	}
    mv.visitVarInsn(ILOAD, 3);
    mv.visitInsn(ICONST_1);
    Label l1 = new Label();
    mv.visitJumpInsn(IF_ICMPNE, l1);
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);
    mv.visitLabel(l1);

    mv.visitVarInsn(ILOAD, 3);
    mv.visitMethodInsn(INVOKESTATIC, "transfer/def/TransferConfig", "getType", "(B)B", false);
    mv.visitVarInsn(ISTORE, 5);

    mv.visitVarInsn(ILOAD, 5);
    mv.visitIntInsn(BIPUSH, Types.ENUM);

    Label l2 = new Label();
    mv.visitJumpInsn(IF_ICMPEQ, l2);
    mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalTypeException");
    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 4);
    mv.visitVarInsn(ILOAD, 5);
    mv.visitIntInsn(BIPUSH, Types.ENUM);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(
        INVOKESPECIAL,
        "transfer/exceptions/IllegalTypeException",
        "<init>",
        "(Ltransfer/core/DeserialContext;BBLjava/lang/reflect/Type;)V",
        false);
    mv.visitInsn(ATHROW);
    mv.visitLabel(l2);

    Class<?> rawClass = TypeUtils.getRawClass(type);

    if (type == null
        || type == Object.class
        || type == Enum.class
        || rawClass.isInterface()
        || Modifier.isAbstract(rawClass.getModifiers()) && !rawClass.isArray()) {

      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false);
      mv.visitVarInsn(ISTORE, 6);

      mv.visitVarInsn(ILOAD, 6);
      mv.visitMethodInsn(
          INVOKESTATIC, "transfer/def/TransferConfig", "getClass", "(I)Ljava/lang/Class;", false);
      mv.visitVarInsn(ASTORE, 7);

      mv.visitVarInsn(ALOAD, 7);
      Label l12 = new Label();
      mv.visitJumpInsn(IFNONNULL, l12);
      mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException");
      mv.visitInsn(DUP);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "transfer/exceptions/UnsupportDeserializerTypeException",
          "<init>",
          "(Ljava/lang/reflect/Type;)V",
          false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l12);

      mv.visitVarInsn(ALOAD, 7);
      mv.visitMethodInsn(
          INVOKESTATIC,
          "transfer/def/TransferConfig",
          "getOrCreateClassInfo",
          "(Ljava/lang/Class;)Ltransfer/core/ClassInfo;",
          false);
      mv.visitTypeInsn(CHECKCAST, "transfer/core/EnumInfo");
      mv.visitVarInsn(ASTORE, 8);
      mv.visitVarInsn(ALOAD, 8);
      Label l15 = new Label();
      mv.visitJumpInsn(IFNONNULL, l15);
      mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException");
      mv.visitInsn(DUP);
      mv.visitVarInsn(ALOAD, 7);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "transfer/exceptions/UnsupportDeserializerTypeException",
          "<init>",
          "(Ljava/lang/reflect/Type;)V",
          false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l15);

      mv.visitVarInsn(ILOAD, 6);
      mv.visitVarInsn(ALOAD, 8);
      mv.visitMethodInsn(INVOKEVIRTUAL, "transfer/core/EnumInfo", "getClassId", "()I", false);
      Label l17 = new Label();
      mv.visitJumpInsn(IF_ICMPEQ, l17);
      mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalClassTypeException");
      mv.visitInsn(DUP);
      mv.visitVarInsn(ALOAD, 4);
      mv.visitVarInsn(ILOAD, 6);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "transfer/exceptions/IllegalClassTypeException",
          "<init>",
          "(Ltransfer/core/DeserialContext;ILjava/lang/reflect/Type;)V",
          false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l17);

      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false);
      mv.visitVarInsn(ISTORE, 9);
      mv.visitVarInsn(ALOAD, 8);
      mv.visitVarInsn(ILOAD, 9);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "transfer/core/EnumInfo", "toEnum", "(I)Ljava/lang/Enum;", false);
      mv.visitInsn(ARETURN);
      mv.visitMaxs(5, 10);
      mv.visitEnd();

    } else {

      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false);
      mv.visitVarInsn(ISTORE, 6);

      mv.visitLdcInsn(
          org.objectweb.asm.Type.getType("L" + AsmUtils.toAsmCls(rawClass.getName()) + ";"));
      mv.visitMethodInsn(
          INVOKESTATIC,
          "transfer/def/TransferConfig",
          "getOrCreateClassInfo",
          "(Ljava/lang/Class;)Ltransfer/core/ClassInfo;",
          false);
      mv.visitTypeInsn(CHECKCAST, "transfer/core/EnumInfo");
      mv.visitVarInsn(ASTORE, 7);
      mv.visitVarInsn(ALOAD, 7);

      Label l15 = new Label();
      mv.visitJumpInsn(IFNONNULL, l15);
      mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException");
      mv.visitInsn(DUP);
      mv.visitLdcInsn(
          org.objectweb.asm.Type.getType("L" + AsmUtils.toAsmCls(rawClass.getName()) + ";"));
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "transfer/exceptions/UnsupportDeserializerTypeException",
          "<init>",
          "(Ljava/lang/reflect/Type;)V",
          false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l15);

      mv.visitVarInsn(ILOAD, 6);
      mv.visitVarInsn(ALOAD, 7);
      mv.visitMethodInsn(INVOKEVIRTUAL, "transfer/core/EnumInfo", "getClassId", "()I", false);
      Label l17 = new Label();
      mv.visitJumpInsn(IF_ICMPEQ, l17);
      mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalClassTypeException");
      mv.visitInsn(DUP);
      mv.visitVarInsn(ALOAD, 4);
      mv.visitVarInsn(ILOAD, 6);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "transfer/exceptions/IllegalClassTypeException",
          "<init>",
          "(Ltransfer/core/DeserialContext;ILjava/lang/reflect/Type;)V",
          false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l17);

      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false);
      mv.visitVarInsn(ISTORE, 8);

      mv.visitVarInsn(ALOAD, 7);
      mv.visitVarInsn(ILOAD, 8);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "transfer/core/EnumInfo", "toEnum", "(I)Ljava/lang/Enum;", false);
      mv.visitInsn(ARETURN);
      mv.visitMaxs(5, 10);
      mv.visitEnd();
    }
  }
Example #12
0
 @Override
 public void visitIntInsn(int opcode, int operand) {
   mtd.addVariableOperation(opcode, operand);
   super.visitIntInsn(opcode, operand);
 }
  @Override
  public void visitIntInsn(int opcode, int operand) {
    _touchBranch();

    super.visitIntInsn(opcode, operand);
  }
Example #14
0
 private void pushPrimitiveConstant(
     final MethodVisitor mv, final Object value, final ClassNode type) {
   boolean isInt = ClassHelper.int_TYPE.equals(type);
   boolean isShort = ClassHelper.short_TYPE.equals(type);
   boolean isByte = ClassHelper.byte_TYPE.equals(type);
   if (isInt || isShort || isByte) {
     int val = isInt ? (Integer) value : isShort ? (Short) value : (Byte) value;
     switch (val) {
       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 (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) {
           mv.visitIntInsn(BIPUSH, val);
         } else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) {
           mv.visitIntInsn(SIPUSH, val);
         } else {
           mv.visitLdcInsn(value);
         }
     }
   } else if (ClassHelper.long_TYPE.equals(type)) {
     if ((Long) value == 0L) {
       mv.visitInsn(LCONST_0);
     } else if ((Long) value == 1L) {
       mv.visitInsn(LCONST_1);
     } else {
       mv.visitLdcInsn(value);
     }
   } else if (ClassHelper.float_TYPE.equals(type)) {
     if ((Float) value == 0f) {
       mv.visitInsn(FCONST_0);
     } else if ((Float) value == 1f) {
       mv.visitInsn(FCONST_1);
     } else if ((Float) value == 2f) {
       mv.visitInsn(FCONST_2);
     } else {
       mv.visitLdcInsn(value);
     }
   } else if (ClassHelper.double_TYPE.equals(type)) {
     if ((Double) value == 0d) {
       mv.visitInsn(DCONST_0);
     } else if ((Double) value == 1d) {
       mv.visitInsn(DCONST_1);
     } else {
       mv.visitLdcInsn(value);
     }
   } else if (ClassHelper.boolean_TYPE.equals(type)) {
     boolean b = (Boolean) value;
     if (b) {
       mv.visitInsn(ICONST_1);
     } else {
       mv.visitInsn(ICONST_0);
     }
   } else {
     mv.visitLdcInsn(value);
   }
 }
  public static byte[] generate(EventClassModel model) {
    ClassWriter cwriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);

    ClassVisitor cw;
    if (TRACE) {
      cw = new TraceClassVisitor(cwriter, new ASMifier(), new PrintWriter(System.out));
      cw = new CheckClassAdapter(cw);
    } else {
      cw = cwriter;
    }

    FieldVisitor fv;
    MethodVisitor mv;

    String concreteClassName =
        model.getRootPackageInternalPrefix() + "event/" + model.technicalNameCapitalized + "Event";
    String className =
        model.isCustomized
            ? model.getRootPackageInternalPrefix()
                + "event/Abstract"
                + model.technicalNameCapitalized
                + "Event"
            : concreteClassName;

    cw.visit(
        V1_7,
        ACC_PUBLIC + ACC_SUPER + (model.isCustomized ? ACC_ABSTRACT : 0),
        className,
        null,
        "org/instantlogic/interaction/flow/impl/SimpleFlowEvent",
        null);

    // public static final HomeEvent
    {
      fv =
          cw.visitField(
              ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
              "INSTANCE",
              "L" + concreteClassName + ";",
              null,
              null);
      fv.visitEnd();
    }

    {
      mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
      mv.visitCode();

      // INSTANCE = new HomeEvent();
      mv.visitTypeInsn(NEW, concreteClassName);
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, concreteClassName, "<init>", "()V");
      mv.visitFieldInsn(PUTSTATIC, className, "INSTANCE", "L" + concreteClassName + ";");

      mv.visitInsn(RETURN);
      mv.visitMaxs(9, 99);
      mv.visitEnd();
    }
    // Default synthetic constructor
    {
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitLdcInsn(model.name);
      mv.visitIntInsn(BIPUSH, model.parameters.size());
      mv.visitTypeInsn(ANEWARRAY, "org/instantlogic/fabric/model/Entity");
      int i = 0;
      for (String parameter : model.parameters) {
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, i);
        mv.visitFieldInsn(
            GETSTATIC,
            model.getRootPackageInternalPrefix() + "entity/" + parameter + "Entity",
            "INSTANCE",
            "L" + model.getRootPackageInternalPrefix() + "entity/" + parameter + "Entity;");
        mv.visitInsn(AASTORE);
        i++;
      }
      mv.visitMethodInsn(
          INVOKESPECIAL,
          "org/instantlogic/interaction/flow/impl/SimpleFlowEvent",
          "<init>",
          "(Ljava/lang/String;[Lorg/instantlogic/fabric/model/Entity;)V");
      mv.visitInsn(RETURN);
      mv.visitMaxs(9, 99);
      mv.visitEnd();
    }

    cw.visitEnd();
    return cwriter.toByteArray();
  }
 protected MethodVisitor makeDelegateToClosureCall(
     final String name,
     final String desc,
     final String signature,
     final String[] exceptions,
     final int accessFlags) {
   MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
   //        TraceMethodVisitor tmv = new TraceMethodVisitor(mv);
   //        mv = tmv;
   mv.visitCode();
   int stackSize = 0;
   // method body should be:
   //  this.$delegate$closure$methodName.call(new Object[] { method arguments })
   Type[] args = Type.getArgumentTypes(desc);
   int arrayStore = args.length + 1;
   BytecodeHelper.pushConstant(mv, args.length);
   mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); // stack size = 1
   stackSize = 1;
   int idx = 1;
   for (int i = 0; i < args.length; i++) {
     Type arg = args[i];
     mv.visitInsn(DUP); // stack size = 2
     BytecodeHelper.pushConstant(mv, i); // array index, stack size = 3
     stackSize = 3;
     // 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
     }
     idx += registerLen(arg);
     stackSize = Math.max(4, 3 + registerLen(arg));
     mv.visitInsn(AASTORE); // store value into array
   }
   mv.visitVarInsn(ASTORE, arrayStore); // store array
   int arrayIndex = arrayStore;
   mv.visitVarInsn(ALOAD, 0); // load this
   mv.visitFieldInsn(
       GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map
   mv.visitLdcInsn(name); // load method name
   mv.visitMethodInsn(
       INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
   arrayStore++;
   mv.visitVarInsn(ASTORE, arrayStore);
   // if null, test if wildcard exists
   Label notNull = new Label();
   mv.visitIntInsn(ALOAD, arrayStore);
   mv.visitJumpInsn(IFNONNULL, notNull);
   mv.visitVarInsn(ALOAD, 0); // load this
   mv.visitFieldInsn(
       GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map
   mv.visitLdcInsn("*"); // load wildcard
   mv.visitMethodInsn(
       INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
   mv.visitVarInsn(ASTORE, arrayStore);
   mv.visitLabel(notNull);
   mv.visitVarInsn(ALOAD, arrayStore);
   mv.visitMethodInsn(
       INVOKESTATIC,
       BytecodeHelper.getClassInternalName(this.getClass()),
       "ensureClosure",
       "(Ljava/lang/Object;)Lgroovy/lang/Closure;");
   mv.visitVarInsn(ALOAD, arrayIndex); // load argument array
   stackSize++;
   mv.visitMethodInsn(
       INVOKEVIRTUAL,
       "groovy/lang/Closure",
       "call",
       "([Ljava/lang/Object;)Ljava/lang/Object;"); // call closure
   unwrapResult(mv, desc);
   mv.visitMaxs(stackSize, arrayStore + 1);
   mv.visitEnd();
   //        System.out.println("tmv.getText() = " + tmv.getText());
   return EMPTY_VISITOR;
 }
Example #17
0
 public void visitIntInsn(int opcode, int operand) {
   visitor.visitIntInsn(opcode, operand);
 }
  @Override
  public DataType visitAtom(@NotNull PythonParser.AtomContext ctx) {
    //        System.out.println("Zz" + ctx.NAME() + ctx.STRING());
    if (ctx.test() != null) { // 1
      return visitTest(ctx.test());
    } else if (ctx.STRING().size() > 0) { // 7,8,9
      String ss = "";
      for (TerminalNode s : ctx.STRING()) {
        ss += s.getText();
      }
      mv.visitLdcInsn(ss.length());
      mv.visitIntInsn(NEWARRAY, T_CHAR);
      int tempIndex = 0;
      for (int i = 0; i < ss.length(); i++) {
        if (!("\"".equals(ss.substring(i, i + 1))) && !("\'".equals(ss.substring(i, i + 1)))) {
          mv.visitInsn(DUP);
          mv.visitLdcInsn(tempIndex);
          mv.visitLdcInsn(ss.charAt(i));
          mv.visitInsn(CASTORE);
          tempIndex++;
        }
      }
      if (ctx.LBRACK() != null) {
        if (Integer.parseInt(ctx.INT().getText()) > tempIndex - 1) {
          throw new CompileException(
              String.format(
                  "Index out of bounds exception for string %s with index %s",
                  ss, Integer.parseInt(ctx.INT().getText())));
        }
        mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText()));
        mv.visitInsn(CALOAD);
        mv.visitMethodInsn(
            INVOKESTATIC,
            Type.getType(String.class).getInternalName(),
            "valueOf",
            "(C)Ljava/lang/String;",
            false);
        return new StringType(1);
      } else {
        mv.visitMethodInsn(
            INVOKESTATIC,
            Type.getType(String.class).getInternalName(),
            "valueOf",
            "([C)Ljava/lang/String;",
            false);
        return new StringType(ss.length());
      }
    } else if (!ctx.NAME().isEmpty()) { // 3,4,5
      DataType type = null;
      //            System.out.println("GG" + ctx.getText() + "GG");
      String varName = ctx.NAME().get(0).getText();
      if (scope.isLocalVariable(varName)) {
        if (ctx.LBRACK() != null) { // 4,5
          type = scope.getLocalVariableType(varName);
          if (!(type instanceof StringType)) {
            throw new CompileException(String.format("Trying to take index not from string!!"));
          }
          mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName));
          if (ctx.INT() != null) {
            mv.visitMethodInsn(
                INVOKEVIRTUAL,
                Type.getType(String.class).getInternalName(),
                "toCharArray",
                "()[C",
                false);
            if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) {
              throw new CompileException(String.format("Index out of bounds exception!"));
            }
            mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText()));
            mv.visitInsn(CALOAD);
            mv.visitMethodInsn(
                INVOKESTATIC,
                Type.getType(String.class).getInternalName(),
                "valueOf",
                "(C)Ljava/lang/String;",
                false);
            return new StringType(1);
          } else if (ctx.NAME(1) != null) {
            varName = ctx.NAME(1).getText();
            type = scope.getLocalVariableType(ctx.NAME(1).getText());
            if (!type.isInteger()) {
              throw new CompileException(
                  String.format("Trying to take index from string not with int!"));
            } else {
              Label okLabel = new Label();
              mv.visitMethodInsn(
                  INVOKEVIRTUAL,
                  Type.getType(String.class).getInternalName(),
                  "toCharArray",
                  "()[C",
                  false);
              mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText()));
              mv.visitInsn(DUP);
              mv.visitLdcInsn(type.getSize());
              mv.visitInsn(SWAP);
              mv.visitJumpInsn(IF_ICMPGT, okLabel);
              mv.visitLabel(okLabel);
              mv.visitInsn(CALOAD);
              mv.visitMethodInsn(
                  INVOKESTATIC,
                  Type.getType(String.class).getInternalName(),
                  "valueOf",
                  "(C)Ljava/lang/String;",
                  false);
              // TODO out of bounds a[b]
              //                            mv.visitLdcInsn("Out of bounds!");
              //                            mv.visitMethodInsn(INVOKESPECIAL,
              //                                    "java/lang/CompilerException", "<init>",
              // "(Ljava/lang/String;)V", false);
              return new StringType(1);
            }

          } else {
            throw new CompileException(String.format("Unidentified operation"));
          }
        } else { // 3
          type = scope.getLocalVariableType(varName);
          mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName));
        }
      } else if (scope.isGlobalVariable(varName)) {
        if (ctx.LBRACK() != null) { // 4,5
          type = scope.getGlobalVariableType(varName);
          if (!(type instanceof StringType)) {
            throw new CompileException(String.format("Trying to take index not from string!!"));
          }
          mv.visitFieldInsn(
              GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor());
          if (ctx.INT() != null) {
            mv.visitMethodInsn(
                INVOKEVIRTUAL,
                Type.getType(String.class).getInternalName(),
                "toCharArray",
                "()[C",
                false);
            if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) {
              throw new CompileException(String.format("Index out of bounds exception!"));
            }
            mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText()));
            mv.visitInsn(CALOAD);
            mv.visitMethodInsn(
                INVOKESTATIC,
                Type.getType(String.class).getInternalName(),
                "valueOf",
                "(C)Ljava/lang/String;",
                false);
            return new StringType(1);
          } else if (ctx.NAME(1) != null) {
            varName = ctx.NAME(1).getText();
            type = scope.getLocalVariableType(ctx.NAME(1).getText());
            if (!type.isInteger()) {
              throw new CompileException(
                  String.format("Trying to take index from string not with int!"));
            } else {
              Label okLabel = new Label();
              mv.visitMethodInsn(
                  INVOKEVIRTUAL,
                  Type.getType(String.class).getInternalName(),
                  "toCharArray",
                  "()[C",
                  false);
              mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText()));
              mv.visitInsn(DUP);
              mv.visitLdcInsn(type.getSize());
              mv.visitInsn(SWAP);
              mv.visitJumpInsn(IF_ICMPGT, okLabel);
              mv.visitLabel(okLabel);
              mv.visitInsn(CALOAD);
              mv.visitMethodInsn(
                  INVOKESTATIC,
                  Type.getType(String.class).getInternalName(),
                  "valueOf",
                  "(C)Ljava/lang/String;",
                  false);
              // TODO out of bounds a[b]
              //                            mv.visitLdcInsn("Out of bounds!");
              //                            mv.visitMethodInsn(INVOKESPECIAL,
              //                                    "java/lang/CompilerException", "<init>",
              // "(Ljava/lang/String;)V", false);
              return new StringType(1);
            }

          } else {
            throw new CompileException(String.format("Unidentified operation"));
          }
        } else { // 3
          type = scope.getGlobalVariableType(varName);
          mv.visitFieldInsn(
              GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor());
        }
      }
      return type;
      //			} else if (scope.isFunction)
    } else if (ctx.INT() != null) { // 6
      mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText()));
      return PrimitiveType.INTEGER;
    } else if (ctx.BOOL() != null) { // 2
      mv.visitInsn("False".equals(ctx.BOOL().getText()) ? ICONST_0 : ICONST_1);
      return PrimitiveType.BOOLEAN;
    } else {
      throw new CompileException(String.format("Undefined thing to work with! %s", ctx.getText()));
    }
  }
Example #19
0
 /*
  * (non-Javadoc)
  *
  * @see org.objectweb.asm.MethodAdapter#visitLdcInsn(java.lang.Object)
  */
 @Override
 public void visitLdcInsn(Object cst) {
   if (cst == null) {
     this.visitInsn(ACONST_NULL);
   } else if (cst instanceof Integer) {
     int value = (Integer) cst;
     if (value >= -1 && value <= 5) {
       super.visitInsn(ICONST_0 + value);
     } else if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
       super.visitIntInsn(BIPUSH, value);
     } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
       super.visitIntInsn(SIPUSH, value);
     } else {
       super.visitLdcInsn(cst);
     }
   } else if (cst instanceof Long) {
     long value = (Long) cst;
     if (value == 0L || value == 1L) {
       super.visitInsn(LCONST_0 + ((int) value));
     } else {
       super.visitLdcInsn(cst);
     }
   } else if (cst instanceof Float) {
     float value = (Float) cst;
     if (value == 0.0F) {
       super.visitInsn(FCONST_0);
     } else if (value == 1.0F) {
       super.visitInsn(FCONST_1);
     } else if (value == 2.0F) {
       super.visitInsn(FCONST_2);
     } else {
       super.visitLdcInsn(cst);
     }
   } else if (cst instanceof Double) {
     double value = (Double) cst;
     if (value == 0.0D) {
       super.visitInsn(DCONST_0);
     } else if (value == 1.0D) {
       super.visitInsn(DCONST_1);
     } else {
       super.visitLdcInsn(cst);
     }
   } else if (cst instanceof Type) {
     Type t = (Type) cst;
     switch (t.getSort()) {
       case Type.BOOLEAN:
         super.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.BYTE:
         super.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.CHAR:
         super.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.DOUBLE:
         super.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.FLOAT:
         super.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.INT:
         super.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.LONG:
         super.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
         break;
       case Type.SHORT:
         super.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
         break;
       default:
         super.visitLdcInsn(cst);
     }
   } else {
     super.visitLdcInsn(cst);
   }
 }