Package org.aspectj.apache.bcel.generic

Examples of org.aspectj.apache.bcel.generic.Type


    bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040 /*
                                         * BRIDGE = 0x00000040
                                         */);
    // UnresolvedType[] newParams =
    // munger.getSignature().getParameterTypes();
    Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType());
    body = bridgeMethod.getBody();
    fact = clazz.getFactory();

    if (!Modifier.isStatic(unMangledInterMethod.getModifiers())) {
      body.append(InstructionFactory.createThis());
      pos++;
    }
    for (int i = 0, len = paramTypes.length; i < len; i++) {
      Type paramType = paramTypes[i];
      body.append(InstructionFactory.createLoad(paramType, pos));
      // if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().
      // equals
      // (unMangledInterMethod.getParameterTypes()[i].getErasureSignature
      // ())) {
      // System.err.println("Putting in cast from "+paramType+" to "+
      // bridgingToParms[i]);
      // body.append(fact.createCast(paramType,bridgingToParms[i]));
      // }
      pos += paramType.getSize();
    }

    body.append(Utility.createInvoke(fact, world, unMangledInterMethod));
    body.append(InstructionFactory.createReturn(returnType));
    clazz.addMethodGen(bridgeMethod);
View Full Code Here


    }

    boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);

    if (shouldApply) {
      Type bcelReturnType = BcelWorld.makeBcelType(introduced.getReturnType());

      // If no implementation class was specified, the intention was that
      // the types matching the pattern
      // already implemented the interface, let's check that now!
      if (munger.getImplClassName() == null && !munger.specifiesDelegateFactoryMethod()) {
        boolean isOK = false;
        List<LazyMethodGen> existingMethods = gen.getMethodGens();
        for (LazyMethodGen m : existingMethods) {
          if (m.getName().equals(introduced.getName())
              && m.getParameterSignature().equals(introduced.getParameterSignature())
              && m.getReturnType().equals(bcelReturnType)) {
            isOK = true;
          }
        }
        if (!isOK) {
          // the class does not implement this method, they needed to
          // supply a default impl class
          IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '" + gen.getName()
              + "' does not implement the method '" + stringifyMember(introduced) + "' defined on the interface '"
              + introduced.getDeclaringType() + "'", weaver.getLazyClassGen().getType().getSourceLocation(), true,
              new ISourceLocation[] { munger.getSourceLocation() });
          weaver.getWorld().getMessageHandler().handleMessage(msg);
          return false;
        }

        return true;
      }

      LazyMethodGen mg = new LazyMethodGen(introduced.getModifiers() - Modifier.ABSTRACT, bcelReturnType,
          introduced.getName(), BcelWorld.makeBcelTypes(introduced.getParameterTypes()),
          BcelWorld.makeBcelTypesAsClassNames(introduced.getExceptions()), gen);

      // annotation copy from annotation on ITD interface
      if (weaver.getWorld().isInJava5Mode()) {
        AnnotationAJ annotationsOnRealMember[] = null;
        ResolvedType toLookOn = weaver.getWorld().lookupOrCreateName(introduced.getDeclaringType());
        if (fromType.isRawType()) {
          toLookOn = fromType.getGenericType();
        }
        // lookup the method
        ResolvedMember[] ms = toLookOn.getDeclaredJavaMethods();
        for (ResolvedMember m : ms) {
          if (introduced.getName().equals(m.getName()) && introduced.getSignature().equals(m.getSignature())) {
            annotationsOnRealMember = m.getAnnotations();
            break;
          }
        }
        if (annotationsOnRealMember != null) {
          for (AnnotationAJ anno : annotationsOnRealMember) {
            AnnotationGen a = ((BcelAnnotation) anno).getBcelAnnotation();
            AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
            mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
          }
        }
      }

      InstructionList body = new InstructionList();
      InstructionFactory fact = gen.getFactory();

      // getfield
      body.append(InstructionConstants.ALOAD_0);
      body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
      InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
      body.append(ifNonNull);

      // Create and store a new instance
      body.append(InstructionConstants.ALOAD_0); // 'this' is where we'll store the field value

      // TODO for non-static case, call aspectOf() then call the factory method on the retval
      // TODO decide whether the value can really be cached

      // locate the aspect and call the static method in it
      if (munger.specifiesDelegateFactoryMethod()) {
        ResolvedMember rm = munger.getDelegateFactoryMethod(weaver.getWorld());

        // Check the method parameter is compatible with the type of the instance to be passed
        if (rm.getArity() != 0) {
          ResolvedType parameterType = rm.getParameterTypes()[0].resolve(weaver.getWorld());
          if (!parameterType.isAssignableFrom(weaver.getLazyClassGen().getType())) {
            signalError("For mixin factory method '" + rm + "': Instance type '" + weaver.getLazyClassGen().getType()
                + "' is not compatible with factory parameter type '" + parameterType + "'", weaver);
            return false;
          }
        }
        if (Modifier.isStatic(rm.getModifiers())) {
          if (rm.getArity() != 0) {
            body.append(InstructionConstants.ALOAD_0);
          }
          body.append(fact.createInvoke(rm.getDeclaringType().getName(), rm.getName(), rm.getSignature(),
              Constants.INVOKESTATIC));
          body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
        } else {
          // Need to call aspectOf() to obtain the aspect instance then call the factory method upon that
          UnresolvedType theAspect = munger.getAspect();
          body.append(fact.createInvoke(theAspect.getName(), "aspectOf", "()" + theAspect.getSignature(),
              Constants.INVOKESTATIC));
          if (rm.getArity() != 0) {
            body.append(InstructionConstants.ALOAD_0);
          }
          body.append(fact.createInvoke(rm.getDeclaringType().getName(), rm.getName(), rm.getSignature(),
              Constants.INVOKEVIRTUAL));
          body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
        }
      } else {
        body.append(fact.createNew(munger.getImplClassName()));
        body.append(InstructionConstants.DUP);
        body.append(fact.createInvoke(munger.getImplClassName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
        body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
      }

      // if not null use the instance we've got
      InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0);
      ifNonNull.setTarget(ifNonNullElse);
      body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));

      // args
      int pos = 0;
      if (!Modifier.isStatic(introduced.getModifiers())) { // skip 'this' (?? can this really
        // happen)
        // body.append(InstructionFactory.createThis());
        pos++;
      }
      Type[] paramTypes = BcelWorld.makeBcelTypes(introduced.getParameterTypes());
      for (int i = 0, len = paramTypes.length; i < len; i++) {
        Type paramType = paramTypes[i];
        body.append(InstructionFactory.createLoad(paramType, pos));
        pos += paramType.getSize();
      }
      body.append(Utility.createInvoke(fact, Constants.INVOKEINTERFACE, introduced));
      body.append(InstructionFactory.createReturn(bcelReturnType));

      mg.getBody().append(body);
View Full Code Here

  }

  private static LazyMethodGen makeDispatcher(LazyClassGen onGen, String dispatchName, ResolvedMember superMethod,
      BcelWorld world, boolean isSuper) {
    Type[] paramTypes = BcelWorld.makeBcelTypes(superMethod.getParameterTypes());
    Type returnType = BcelWorld.makeBcelType(superMethod.getReturnType());

    int modifiers = Modifier.PUBLIC;
    if (onGen.isInterface()) {
      modifiers |= Modifier.ABSTRACT;
    }

    LazyMethodGen mg = new LazyMethodGen(modifiers, returnType, dispatchName, paramTypes, UnresolvedType.getNames(superMethod
        .getExceptions()), onGen);
    InstructionList body = mg.getBody();

    if (onGen.isInterface()) {
      return mg;
    }

    // assert (!superMethod.isStatic())
    InstructionFactory fact = onGen.getFactory();
    int pos = 0;

    body.append(InstructionFactory.createThis());
    pos++;
    for (int i = 0, len = paramTypes.length; i < len; i++) {
      Type paramType = paramTypes[i];
      body.append(InstructionFactory.createLoad(paramType, pos));
      pos += paramType.getSize();
    }
    if (isSuper) {
      body.append(Utility.createSuperInvoke(fact, world, superMethod));
    } else {
      body.append(Utility.createInvoke(fact, world, superMethod));
View Full Code Here

      }
      weaver.addInitializer(this);
      // System.err.println("impl body on " + gen.getType() + " for " +
      // munger);

      Type fieldType = BcelWorld.makeBcelType(field.getType());

      FieldGen fg = makeFieldGen(gen, AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType));

      if (annotationsOnRealMember != null) {
        for (int i = 0; i < annotationsOnRealMember.length; i++) {
View Full Code Here

    InstructionFactory fact;
    LazyMethodGen bridgeMethod = makeMethodGen(gen, bridgingSetter);
    bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040); // BRIDGE = 0x00000040
    Type[] paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
    Type[] bridgingToParms = BcelWorld.makeBcelTypes(itdfieldSetter.getParameterTypes());
    Type returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
    InstructionList body = bridgeMethod.getBody();
    fact = gen.getFactory();
    int pos = 0;

    if (!Modifier.isStatic(bridgingSetter.getModifiers())) {
      body.append(InstructionFactory.createThis());
      pos++;
    }
    for (int i = 0, len = paramTypes.length; i < len; i++) {
      Type paramType = paramTypes[i];
      body.append(InstructionFactory.createLoad(paramType, pos));
      if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(
          itdfieldSetter.getParameterTypes()[i].getErasureSignature())) {
        body.append(fact.createCast(paramType, bridgingToParms[i]));
      }
      pos += paramType.getSize();
    }

    body.append(Utility.createInvoke(fact, weaver.getWorld(), itdfieldSetter));
    body.append(InstructionFactory.createReturn(returnType));
    gen.addMethodGen(bridgeMethod);
View Full Code Here

    Expr[] args = call.getArgs();
    // System.out.println("args: " + Arrays.asList(args));
    InstructionList callIl = new InstructionList();
    for (int i = 0, len = args.length; i < len; i++) {
      // XXX only correct for static method calls
      Type desiredType = BcelWorld.makeBcelType(method.getParameterTypes()[i]);
      Expr arg = args[i];
      // if arg is null it is because we couldn't bind it properly, for example see 162135
      if (arg == null) {
        InstructionList iList = new InstructionList();
        iList.append(InstructionFactory.createNull(desiredType));
View Full Code Here

      if (!isStatic()) {
        String cname = this.enclosingClass.getClassName();
        if (cname == null) {
          return; // give up for now
        }
        Type enclosingType = BcelWorld.makeBcelType(UnresolvedType.forName(cname));
        gen.addLocalVariable("this", enclosingType, slot++, start, end);
      }
      // Add entries for the method arguments
      String[] paramNames = (memberView == null ? null : memberView.getParameterNames());
      if (paramNames != null) {
View Full Code Here

      } else if (slots.contains(new Integer(tag.getSlot()))) {
        // we already have a var starting at this tag with this slot
        continue;
      }
      slots.add(Integer.valueOf(tag.getSlot()));
      Type t = tag.getRealType();
      if (t == null) {
        t = BcelWorld.makeBcelType(UnresolvedType.forSignature(tag.getType()));
      }
      gen.addLocalVariable(tag.getName(), t, tag.getSlot(), start, lvpos.end);
    }
View Full Code Here

    if ((newflags & 0x00000100) != 0) {
      newflags = newflags - 0x100;// NATIVE = 0x00000100 - need to clear it
    }

    bridgeMethod.setAccessFlags(newflags);
    Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType());
    Type[] paramTypes = BcelWorld.makeBcelTypes(theBridgeMethod.getParameterTypes());
    Type[] newParamTypes = whatToBridgeToMethodGen.getArgumentTypes();
    body = bridgeMethod.getBody();
    fact = clazz.getFactory();

    if (!whatToBridgeToMethodGen.isStatic()) {
      body.append(InstructionFactory.createThis());
      pos++;
    }
    for (int i = 0, len = paramTypes.length; i < len; i++) {
      Type paramType = paramTypes[i];
      body.append(InstructionFactory.createLoad(paramType, pos));
      if (!newParamTypes[i].equals(paramTypes[i])) {
        if (world.forDEBUG_bridgingCode) {
          System.err.println("Bridging: Cast " + newParamTypes[i] + " from " + paramTypes[i]);
        }
        body.append(fact.createCast(paramTypes[i], newParamTypes[i]));
      }
      pos += paramType.getSize();
    }

    body.append(Utility.createInvoke(fact, world, whatToBridgeTo));
    body.append(InstructionFactory.createReturn(returnType));
    clazz.addMethodGen(bridgeMethod);
View Full Code Here

    // System.err.println("DEBUG: Transforming synchronized method: "+
    // synchronizedMethod.getName());
    final InstructionFactory fact = synchronizedMethod.getEnclosingClass().getFactory();
    InstructionList body = synchronizedMethod.getBody();
    InstructionList prepend = new InstructionList();
    Type enclosingClassType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType());

    // STATIC METHOD TRANSFORMATION
    if (synchronizedMethod.isStatic()) {

      // What to do here depends on the level of the class file!
      // LDC can handle class literals in Java5 and above *sigh*
      if (synchronizedMethod.getEnclosingClass().isAtLeastJava5()) {
        // MONITORENTER logic:
        // 0: ldc #2; //class C
        // 2: dup
        // 3: astore_0
        // 4: monitorenter
        int slotForLockObject = synchronizedMethod.allocateLocal(enclosingClassType);
        prepend.append(fact.createConstant(enclosingClassType));
        prepend.append(InstructionFactory.createDup(1));
        prepend.append(InstructionFactory.createStore(enclosingClassType, slotForLockObject));
        prepend.append(InstructionFactory.MONITORENTER);

        // MONITOREXIT logic:

        // We basically need to wrap the code from the method in a
        // finally block that
        // will ensure monitorexit is called. Content on the finally
        // block seems to
        // be always:
        //
        // E1: ALOAD_1
        // MONITOREXIT
        // ATHROW
        //
        // so lets build that:
        InstructionList finallyBlock = new InstructionList();
        finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class), slotForLockObject));
        finallyBlock.append(InstructionConstants.MONITOREXIT);
        finallyBlock.append(InstructionConstants.ATHROW);

        // finally -> E1
        // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line
        // 21)
        // | LDC "hello"
        // | INVOKEVIRTUAL java.io.PrintStream.println
        // (Ljava/lang/String;)V
        // | ALOAD_1 (line 20)
        // | MONITOREXIT
        // finally -> E1
        // GOTO L0
        // finally -> E1
        // | E1: ALOAD_1
        // | MONITOREXIT
        // finally -> E1
        // ATHROW
        // L0: RETURN (line 23)

        // search for 'returns' and make them jump to the
        // aload_<n>,monitorexit
        InstructionHandle walker = body.getStart();
        List<InstructionHandle> rets = new ArrayList<InstructionHandle>();
        while (walker != null) {
          if (walker.getInstruction().isReturnInstruction()) {
            rets.add(walker);
          }
          walker = walker.getNext();
        }
        if (!rets.isEmpty()) {
          // need to ensure targeters for 'return' now instead target
          // the load instruction
          // (so we never jump over the monitorexit logic)

          for (Iterator<InstructionHandle> iter = rets.iterator(); iter.hasNext();) {
            InstructionHandle element = iter.next();
            InstructionList monitorExitBlock = new InstructionList();
            monitorExitBlock.append(InstructionFactory.createLoad(enclosingClassType, slotForLockObject));
            monitorExitBlock.append(InstructionConstants.MONITOREXIT);
            // monitorExitBlock.append(Utility.copyInstruction(element
            // .getInstruction()));
            // element.setInstruction(InstructionFactory.createLoad(
            // classType,slotForThis));
            InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock);

            // now move the targeters from the RET to the start of
            // the monitorexit block
            for (InstructionTargeter targeter : element.getTargetersCopy()) {
              // what kinds are there?
              if (targeter instanceof LocalVariableTag) {
                // ignore
              } else if (targeter instanceof LineNumberTag) {
                // ignore
                // } else if (targeter instanceof
                // InstructionBranch &&
                // ((InstructionBranch)targeter).isGoto()) {
                // // move it...
                // targeter.updateTarget(element,
                // monitorExitBlockStart);
              } else if (targeter instanceof InstructionBranch) {
                // move it
                targeter.updateTarget(element, monitorExitBlockStart);
              } else {
                throw new BCException("Unexpected targeter encountered during transform: " + targeter);
              }
            }
          }
        }

        // now the magic, putting the finally block around the code
        InstructionHandle finallyStart = finallyBlock.getStart();

        InstructionHandle tryPosition = body.getStart();
        InstructionHandle catchPosition = body.getEnd();
        body.insert(body.getStart(), prepend); // now we can put the
        // monitorenter stuff on
        synchronizedMethod.getBody().append(finallyBlock);
        synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false);
        synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false);
      } else {

        // TRANSFORMING STATIC METHOD ON PRE JAVA5

        // Hideous nightmare, class literal references prior to Java5

        // YIKES! this is just the code for MONITORENTER !
        // 0: getstatic #59; //Field class$1:Ljava/lang/Class;
        // 3: dup
        // 4: ifnonnull 32
        // 7: pop
        // try
        // 8: ldc #61; //String java.lang.String
        // 10: invokestatic #44; //Method
        // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        // 13: dup
        // catch
        // 14: putstatic #59; //Field class$1:Ljava/lang/Class;
        // 17: goto 32
        // 20: new #46; //class java/lang/NoClassDefFoundError
        // 23: dup_x1
        // 24: swap
        // 25: invokevirtual #52; //Method
        // java/lang/Throwable.getMessage:()Ljava/lang/String;
        // 28: invokespecial #54; //Method
        // java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
        // 31: athrow
        // 32: dup <-- partTwo (branch target)
        // 33: astore_0
        // 34: monitorenter
        //
        // plus exceptiontable entry!
        // 8 13 20 Class java/lang/ClassNotFoundException
        Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType());
        Type clazzType = Type.getType(Class.class);

        InstructionList parttwo = new InstructionList();
        parttwo.append(InstructionFactory.createDup(1));
        int slotForThis = synchronizedMethod.allocateLocal(classType);
        parttwo.append(InstructionFactory.createStore(clazzType, slotForThis)); // ? should be the real type ? String or
        // something?
        parttwo.append(InstructionFactory.MONITORENTER);

        String fieldname = synchronizedMethod.getEnclosingClass().allocateField("class$");
        FieldGen f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE, Type.getType(Class.class), fieldname,
            synchronizedMethod.getEnclosingClass().getConstantPool());
        synchronizedMethod.getEnclosingClass().addField(f, null);

        // 10: invokestatic #44; //Method
        // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
        // 13: dup
        // 14: putstatic #59; //Field class$1:Ljava/lang/Class;
        // 17: goto 32
        // 20: new #46; //class java/lang/NoClassDefFoundError
        // 23: dup_x1
        // 24: swap
        // 25: invokevirtual #52; //Method
        // java/lang/Throwable.getMessage:()Ljava/lang/String;
        // 28: invokespecial #54; //Method
        // java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
        // 31: athrow
        String name = synchronizedMethod.getEnclosingClass().getName();

        prepend.append(fact.createGetStatic(name, fieldname, Type.getType(Class.class)));
        prepend.append(InstructionFactory.createDup(1));
        prepend.append(InstructionFactory.createBranchInstruction(Constants.IFNONNULL, parttwo.getStart()));
        prepend.append(InstructionFactory.POP);

        prepend.append(fact.createConstant(name));
        InstructionHandle tryInstruction = prepend.getEnd();
        prepend.append(fact.createInvoke("java.lang.Class", "forName", clazzType,
            new Type[] { Type.getType(String.class) }, Constants.INVOKESTATIC));
        InstructionHandle catchInstruction = prepend.getEnd();
        prepend.append(InstructionFactory.createDup(1));

        prepend.append(fact.createPutStatic(synchronizedMethod.getEnclosingClass().getType().getName(), fieldname,
            Type.getType(Class.class)));
        prepend.append(InstructionFactory.createBranchInstruction(Constants.GOTO, parttwo.getStart()));

        // start of catch block
        InstructionList catchBlockForLiteralLoadingFail = new InstructionList();
        catchBlockForLiteralLoadingFail.append(fact.createNew((ObjectType) Type.getType(NoClassDefFoundError.class)));
        catchBlockForLiteralLoadingFail.append(InstructionFactory.createDup_1(1));
        catchBlockForLiteralLoadingFail.append(InstructionFactory.SWAP);
        catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.Throwable", "getMessage",
            Type.getType(String.class), new Type[] {}, Constants.INVOKEVIRTUAL));
        catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.NoClassDefFoundError", "<init>", Type.VOID,
            new Type[] { Type.getType(String.class) }, Constants.INVOKESPECIAL));
        catchBlockForLiteralLoadingFail.append(InstructionFactory.ATHROW);
        InstructionHandle catchBlockStart = catchBlockForLiteralLoadingFail.getStart();
        prepend.append(catchBlockForLiteralLoadingFail);
        prepend.append(parttwo);
        // MONITORENTER
        // pseudocode: load up 'this' (var0), dup it, store it in a new
        // local var (for use with monitorexit) and call
        // monitorenter:
        // ALOAD_0, DUP, ASTORE_<n>, MONITORENTER
        // prepend.append(InstructionFactory.createLoad(classType,0));
        // prepend.append(InstructionFactory.createDup(1));
        // int slotForThis =
        // synchronizedMethod.allocateLocal(classType);
        // prepend.append(InstructionFactory.createStore(classType,
        // slotForThis));
        // prepend.append(InstructionFactory.MONITORENTER);

        // MONITOREXIT
        // here be dragons

        // We basically need to wrap the code from the method in a
        // finally block that
        // will ensure monitorexit is called. Content on the finally
        // block seems to
        // be always:
        //
        // E1: ALOAD_1
        // MONITOREXIT
        // ATHROW
        //
        // so lets build that:
        InstructionList finallyBlock = new InstructionList();
        finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class), slotForThis));
        finallyBlock.append(InstructionConstants.MONITOREXIT);
        finallyBlock.append(InstructionConstants.ATHROW);

        // finally -> E1
        // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line
        // 21)
        // | LDC "hello"
        // | INVOKEVIRTUAL java.io.PrintStream.println
        // (Ljava/lang/String;)V
        // | ALOAD_1 (line 20)
        // | MONITOREXIT
        // finally -> E1
        // GOTO L0
        // finally -> E1
        // | E1: ALOAD_1
        // | MONITOREXIT
        // finally -> E1
        // ATHROW
        // L0: RETURN (line 23)
        // frameEnv.put(donorFramePos, thisSlot);

        // search for 'returns' and make them to the
        // aload_<n>,monitorexit
        InstructionHandle walker = body.getStart();
        List<InstructionHandle> rets = new ArrayList<InstructionHandle>();
        while (walker != null) { // !walker.equals(body.getEnd())) {
          if (walker.getInstruction().isReturnInstruction()) {
            rets.add(walker);
          }
          walker = walker.getNext();
        }
        if (rets.size() > 0) {
          // need to ensure targeters for 'return' now instead target
          // the load instruction
          // (so we never jump over the monitorexit logic)

          for (InstructionHandle ret : rets) {
            // System.err.println("Adding monitor exit block at "+
            // element);
            InstructionList monitorExitBlock = new InstructionList();
            monitorExitBlock.append(InstructionFactory.createLoad(classType, slotForThis));
            monitorExitBlock.append(InstructionConstants.MONITOREXIT);
            // monitorExitBlock.append(Utility.copyInstruction(element
            // .getInstruction()));
            // element.setInstruction(InstructionFactory.createLoad(
            // classType,slotForThis));
            InstructionHandle monitorExitBlockStart = body.insert(ret, monitorExitBlock);

            // now move the targeters from the RET to the start of
            // the monitorexit block
            for (InstructionTargeter targeter : ret.getTargetersCopy()) {
              // what kinds are there?
              if (targeter instanceof LocalVariableTag) {
                // ignore
              } else if (targeter instanceof LineNumberTag) {
                // ignore
                // } else if (targeter instanceof GOTO ||
                // targeter instanceof GOTO_W) {
                // // move it...
                // targeter.updateTarget(element,
                // monitorExitBlockStart);
              } else if (targeter instanceof InstructionBranch) {
                // move it
                targeter.updateTarget(ret, monitorExitBlockStart);
              } else {
                throw new BCException("Unexpected targeter encountered during transform: " + targeter);
              }
            }
          }
        }
        // body =
        // rewriteWithMonitorExitCalls(body,fact,true,slotForThis,
        // classType);
        // synchronizedMethod.setBody(body);

        // now the magic, putting the finally block around the code
        InstructionHandle finallyStart = finallyBlock.getStart();

        InstructionHandle tryPosition = body.getStart();
        InstructionHandle catchPosition = body.getEnd();
        body.insert(body.getStart(), prepend); // now we can put the
        // monitorenter stuff on

        synchronizedMethod.getBody().append(finallyBlock);
        synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false);
        synchronizedMethod.addExceptionHandler(tryInstruction, catchInstruction, catchBlockStart,
            (ObjectType) Type.getType(ClassNotFoundException.class), true);
        synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false);
      }
    } else {

      // TRANSFORMING NON STATIC METHOD
      Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType());
      // MONITORENTER
      // pseudocode: load up 'this' (var0), dup it, store it in a new
      // local var (for use with monitorexit) and call
      // monitorenter:
      // ALOAD_0, DUP, ASTORE_<n>, MONITORENTER
View Full Code Here

TOP

Related Classes of org.aspectj.apache.bcel.generic.Type

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.