Package railo.transformer.bytecode.op

Source Code of railo.transformer.bytecode.op.OpElvis

package railo.transformer.bytecode.op;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

import railo.runtime.op.Elvis;
import railo.transformer.bytecode.BytecodeContext;
import railo.transformer.bytecode.BytecodeException;
import railo.transformer.bytecode.Literal;
import railo.transformer.bytecode.expression.Expression;
import railo.transformer.bytecode.expression.ExpressionBase;
import railo.transformer.bytecode.expression.var.DataMember;
import railo.transformer.bytecode.expression.var.Member;
import railo.transformer.bytecode.expression.var.Variable;
import railo.transformer.bytecode.util.ASMUtil;
import railo.transformer.bytecode.util.ExpressionUtil;
import railo.transformer.bytecode.util.Types;
import railo.transformer.bytecode.visitor.ArrayVisitor;

public final class OpElvis extends ExpressionBase {

 

    private static final Type ELVIS=Type.getType(Elvis.class);
    public static final Method INVOKE_STR = new Method(
        "operate",
        Types.BOOLEAN_VALUE,
        new Type[]{Types.PAGE_CONTEXT,Types.DOUBLE_VALUE,Types.STRING_ARRAY});
 
    public static final Method INVOKE_KEY = new Method(
        "operate",
        Types.BOOLEAN_VALUE,
        new Type[]{Types.PAGE_CONTEXT,Types.DOUBLE_VALUE,Types.COLLECTION_KEY_ARRAY});
 
  private Variable left;
    private Expression right;

    /**
     *
     * @see railo.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
     */
    public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
      if(ASMUtil.hasOnlyDataMembers(left))return _writeOutPureDataMember(bc, mode);
     
     
     
     
     
     
     
     
     
      Label notNull = new Label();
      Label end = new Label();
     
      GeneratorAdapter ga = bc.getAdapter();
     
      int l = ga.newLocal(Types.OBJECT);
      ExpressionUtil.visitLine(bc, left.getStart());
      left.writeOut(bc, MODE_REF);
      ExpressionUtil.visitLine(bc, left.getEnd());
      ga.dup();
      ga.storeLocal(l);
     
      ga.visitJumpInsn(Opcodes.IFNONNULL, notNull);
      ExpressionUtil.visitLine(bc, right.getStart());
      right.writeOut(bc, MODE_REF);
      ExpressionUtil.visitLine(bc, right.getEnd());
      ga.visitJumpInsn(Opcodes.GOTO, end);
      ga.visitLabel(notNull);
      ga.loadLocal(l);
      ga.visitLabel(end);
     
      return Types.OBJECT;
    }
   
   
    public Type _writeOutPureDataMember(BytecodeContext bc, int mode) throws BytecodeException {
      // TODO use function isNull for this
      GeneratorAdapter adapter = bc.getAdapter();
     
      Label yes = new Label();
      Label end = new Label();
     
      List<Member> members = left.getMembers();
     
     
     
      // to array
      Iterator<Member> it = members.iterator();
      List<DataMember> list=new ArrayList<DataMember>();
      while(it.hasNext()){
        list.add((DataMember) it.next());
      }
      DataMember[] arr = list.toArray(new DataMember[members.size()]);
     
      ExpressionUtil.visitLine(bc, left.getStart());
     
    // public static boolean call(PageContext pc , double scope,String[] varNames)
      // pc
      adapter.loadArg(0);
      // scope
    adapter.push((double)left.getScope());
    //varNames
   
    // all literal string?
    boolean allLiteral=true;
    for(int i=0;i<arr.length;i++){
      if(!(arr[i].getName() instanceof Literal)) allLiteral=false;
    }
   
    ArrayVisitor av=new ArrayVisitor();
    if(!allLiteral) {
      // String Array
          av.visitBegin(adapter,Types.STRING,arr.length);
          for(int i=0;i<arr.length;i++){
        av.visitBeginItem(adapter, i);
          arr[i].getName().writeOut(bc, MODE_REF);
        av.visitEndItem(adapter);
          }
    }
    else {
      // Collection.Key Array
          av.visitBegin(adapter,Types.COLLECTION_KEY,arr.length);
          for(int i=0;i<arr.length;i++){
        av.visitBeginItem(adapter, i);
          Variable.registerKey(bc, arr[i].getName());
        av.visitEndItem(adapter);
          }
    }
        av.visitEnd();
   
       
        // allowNull
        //adapter.push(false);
   
       
       
    //ASMConstants.NULL(adapter);
   
        // call IsDefined.invoke
      adapter.invokeStatic(ELVIS, allLiteral?INVOKE_KEY:INVOKE_STR);
    ExpressionUtil.visitLine(bc, left.getEnd());
     
     
      adapter.visitJumpInsn(Opcodes.IFEQ, yes);
     
      // left
      ExpressionUtil.visitLine(bc, left.getStart());
      left.writeOut(bc, MODE_REF);
      ExpressionUtil.visitLine(bc, left.getEnd());
      adapter.visitJumpInsn(Opcodes.GOTO, end);
     
      // right
      ExpressionUtil.visitLine(bc, right.getStart());
      adapter.visitLabel(yes);
      right.writeOut(bc, MODE_REF);
      ExpressionUtil.visitLine(bc, right.getEnd());
      adapter.visitLabel(end);
     
      return Types.OBJECT;
     
    }
   

   
   
   
   
   
    private OpElvis(Variable left, Expression right) {
        super(left.getStart(),right.getEnd());
        this.left=left;
        this.right=right; 
    }
   

    public static Expression toExpr(Variable left, Expression right) {
        return new OpElvis(left,right);
    }
}
TOP

Related Classes of railo.transformer.bytecode.op.OpElvis

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.