Package cn.wensiqun.asmsupport.block

Source Code of cn.wensiqun.asmsupport.block.Synchronized

/**
*
*/
package cn.wensiqun.asmsupport.block;


import org.objectweb.asm.Label;
import org.objectweb.asm.Type;

import cn.wensiqun.asmsupport.Executeable;
import cn.wensiqun.asmsupport.Parameterized;
import cn.wensiqun.asmsupport.block.method.SuperMethodBody;
import cn.wensiqun.asmsupport.clazz.AClass;
import cn.wensiqun.asmsupport.definition.variable.LocalVariable;
import cn.wensiqun.asmsupport.operators.Return;
import cn.wensiqun.asmsupport.operators.asmdirect.DUP;
import cn.wensiqun.asmsupport.operators.asmdirect.Marker;


/**
* @author 温斯群(Joe Wen)
*
*/
public abstract class Synchronized extends ProgramBlock {

  private Parameterized lock;
  private LocalVariable dupSynArgument;
 
  private Label monitorenter;
  private Label monitorexit;
  private Label excetpionStart;
  private Label excetpionEnd;
  private Label returnLbl;
 
  private Marker flag1;

  public Synchronized(Parameterized lock) {
    super();
    this.lock = lock;
    monitorenter = new Label();
    monitorexit = new Label();
    excetpionStart = new Label();
    excetpionEnd = new Label();
    returnLbl = new Label();
  }
 
  @Override
  public void setReturned(boolean returned) {
    super.setReturned(returned);
    getOwnerBlock().setReturned(returned);
  }

  @Override
  protected void init() {
    if (lock.getParamterizedType() == null ||
        lock.getParamterizedType().isPrimitive() ||
        lock.getParamterizedType().getType().equals(Type.VOID_TYPE)) {
      throw new IllegalArgumentException(
          lock
              + " is not a valid type's argument for the synchronized statement");
    }
    lock.asArgument();

        SuperMethodBody mb = getMethodBody();
        mb.addTryCatchInfo(monitorenter, monitorexit, excetpionStart, null);
        mb.addTryCatchInfo(excetpionStart, excetpionEnd, excetpionStart, null);
  }

  @Override
  public void executing() {
        Executeable returnInsn = null;
       
    lock.loadToStack(this);
    for (Executeable e : getExecuteQueue()) {
      if(e.equals(flag1)){
        //e.execute();
        insnHelper.monitorEnter();
        insnHelper.mark(monitorenter);
        continue;
      }else if(e instanceof Return){
        returnInsn = e;
        break;
      }
     
      e.execute();
    }

    dupSynArgument.loadToStack(this);
    insnHelper.monitorExit();
    insnHelper.mark(monitorexit);
    insnHelper.goTo(returnLbl);
   
        //for exception
    insnHelper.nop();
    insnHelper.mark(excetpionStart);
    dupSynArgument.loadToStack(this);
    insnHelper.monitorExit();
    insnHelper.getMv().getStack().push(AClass.THROWABLE_ACLASS.getType());
    insnHelper.mark(excetpionEnd);
    insnHelper.throwException();
   
    insnHelper.mark(returnLbl);
    if(returnInsn != null){
      returnInsn.execute();
    }
  }
 
  @Override
  public void generateInsn() {
    dupSynArgument = createVariable(null, lock.getParamterizedType(), true, new DUP(this, lock.getParamterizedType()));
    flag1 = new Marker(this, new Label());
        generateBody(lock);
  }

  public abstract void generateBody(Parameterized synObj);
}
TOP

Related Classes of cn.wensiqun.asmsupport.block.Synchronized

TOP
Copyright © 2018 www.massapi.com. 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.