Package railo.transformer.bytecode.statement.tag

Source Code of railo.transformer.bytecode.statement.tag.TagLoop

package railo.transformer.bytecode.statement.tag;

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.commons.io.IOUtil;
import railo.commons.io.res.util.ResourceUtil;
import railo.runtime.exp.TemplateException;
import railo.transformer.bytecode.BytecodeContext;
import railo.transformer.bytecode.BytecodeException;
import railo.transformer.bytecode.Position;
import railo.transformer.bytecode.cast.CastBoolean;
import railo.transformer.bytecode.expression.Expression;
import railo.transformer.bytecode.statement.FlowControlBreak;
import railo.transformer.bytecode.statement.FlowControlContinue;
import railo.transformer.bytecode.statement.FlowControlFinal;
import railo.transformer.bytecode.statement.ForEach;
import railo.transformer.bytecode.util.ASMConstants;
import railo.transformer.bytecode.util.ExpressionUtil;
import railo.transformer.bytecode.util.Methods;
import railo.transformer.bytecode.util.Methods_Caster;
import railo.transformer.bytecode.util.Types;
import railo.transformer.bytecode.visitor.DecisionDoubleVisitor;
import railo.transformer.bytecode.visitor.DecisionIntVisitor;
import railo.transformer.bytecode.visitor.DecisionObjectVisitor;
import railo.transformer.bytecode.visitor.DoWhileVisitor;
import railo.transformer.bytecode.visitor.ForDoubleVisitor;
import railo.transformer.bytecode.visitor.ForVisitor;
import railo.transformer.bytecode.visitor.LoopVisitor;
import railo.transformer.bytecode.visitor.OnFinally;
import railo.transformer.bytecode.visitor.TryFinallyVisitor;
import railo.transformer.bytecode.visitor.WhileVisitor;

public final class TagLoop extends TagGroup implements FlowControlBreak,FlowControlContinue {


  public static final int TYPE_FILE = 1;
  public static final int TYPE_LIST = 2;
  public static final int TYPE_INDEX = 3;
  public static final int TYPE_CONDITION = 4;
  public static final int TYPE_QUERY = 5;
  public static final int TYPE_COLLECTION = 6;
  public static final int TYPE_ARRAY = 7;
  public static final int TYPE_GROUP = 8;
  public static final int TYPE_INNER_GROUP = 9;
  public static final int TYPE_INNER_QUERY = 10;
  public static final int TYPE_NOTHING = 11;
 

 

  // VariableReference getVariableReference(PageContext pc,String var)
  private static final Method GET_VARIABLE_REFERENCE = new Method(
      "getVariableReference",
      Types.VARIABLE_REFERENCE,
      new Type[]{Types.PAGE_CONTEXT,Types.STRING});


  // Object set(PageContext pc, Object value)
  private static final Method SET = new Method(
      "set",
      Types.OBJECT,
      new Type[]{Types.PAGE_CONTEXT,Types.OBJECT});
  // Object set(double value)
  private static final Method SET_DOUBLE = new Method(
      "set",
      Types.VOID,
      new Type[]{Types.DOUBLE_VALUE});

 

  /*private static final Method KEYS = new Method(
      "keyIterator",
      Types.COLLECTION_KEY_ARRAY,
      new Type[]{});*/

  private static final Method GET = new Method(
      "get",
      Types.OBJECT,
      new Type[]{Types.INT_VALUE,Types.OBJECT});

  private static final Method NEXT = new Method(
      "next",
      Types.OBJECT,
      new Type[]{});

  private static final Method HAS_NEXT = new Method(
      "hasNext",
      Types.BOOLEAN_VALUE,
      new Type[]{});

  // File toFileExisting(PageContext pc ,String destination)
  private static final Type RESOURCE_UTIL = Type.getType(ResourceUtil.class);
  private static final Method TO_RESOURCE_EXISTING = new Method(
      "toResourceExisting",
      Types.RESOURCE,
      new Type[]{Types.PAGE_CONTEXT,Types.STRING});

  // Config getConfig()
  private static final Method GET_CONFIG = new Method(
      "getConfig",
      Types.CONFIG_WEB,
      new Type[]{});

  // SecurityManager getSecurityManager()
  private static final Method GET_SECURITY_MANAGER = new Method(
      "getSecurityManager",
      Types.SECURITY_MANAGER,
      new Type[]{});

  // void checkFileLocation(File file)
  private static final Method CHECK_FILE_LOCATION = new Method(
      "checkFileLocation",
      Types.VOID,
      new Type[]{Types.RESOURCE});

  // Reader getReader(File file, String charset)
  private static final Type IO_UTIL = Type.getType(IOUtil.class);
  private static final Method GET_BUFFERED_READER = new Method(
      "getBufferedReader",
      Types.BUFFERED_READER,
      new Type[]{Types.RESOURCE,Types.STRING});

  // void closeEL(Reader r)
  private static final Method CLOSE_EL = new Method(
      "closeEL",
      Types.VOID,
      new Type[]{Types.READER});

  // String readLine()
  private static final Method READ_LINE = new Method(
      "readLine",
      Types.STRING,
      new Type[]{});
 

  // Array listToArrayRemoveEmpty(String list, String delimiter)
  private static final Method LIST_TO_ARRAY_REMOVE_EMPTY_SS = new Method(
      "listToArrayRemoveEmpty",
      Types.ARRAY,
      new Type[]{Types.STRING,Types.STRING});
 
  // Array listToArrayRemoveEmpty(String list, char delimiter)
  private static final Method LIST_TO_ARRAY_REMOVE_EMPTY_SC = new Method(
      "listToArrayRemoveEmpty",
      Types.ARRAY,
      new Type[]{Types.STRING,Types.CHAR});

  private static final Method SIZE =  new Method(
      "size",
      Types.INT_VALUE,
      new Type[]{});


  // Object get(int key) klo
  private static final Method GETE = new Method(
      "getE",
      Types.OBJECT,
      new Type[]{Types.INT_VALUE});




  // Query getQuery(String key)
  public static final Method GET_QUERY_OBJ = new Method(
      "getQuery",
      Types.QUERY,
      new Type[]{Types.OBJECT});
  public static final Method GET_QUERY_STRING = new Method(
      "getQuery",
      Types.QUERY,
      new Type[]{Types.STRING});

  // int getCurrentrow()
  static final Method GET_CURRENTROW_1 = new Method(
      "getCurrentrow",
      Types.INT_VALUE,
      new Type[]{Types.INT_VALUE});

  static final Method GO = new Method(
      "go",
      Types.BOOLEAN_VALUE,
      new Type[]{Types.INT_VALUE,Types.INT_VALUE});

  static final Method GET_ID = new Method(
      "getId",
      Types.INT_VALUE,
      new Type[]{});
  private static final Method READ = new Method(
      "read",
      Types.STRING,
      new Type[]{Types.READER,Types.INT_VALUE});
  private static final Method ENTRY_ITERATOR = new Method("entryIterator",Types.ITERATOR,new Type[]{});
  private static final Method GET_KEY = new Method("getKey",Types.OBJECT,new Type[]{});
  private static final Method GET_VALUE = new Method("getValue",Types.OBJECT,new Type[]{});
 
 
 
 
 
  private int type;
  private LoopVisitor loopVisitor;
  private String label;

  public TagLoop(Position start,Position end) {
    super(start,end);
  }

  public void setType(int type) {
    this.type=type;
  }
 

  /**
   *
   * @see railo.transformer.bytecode.statement.tag.TagBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter)
   */
  public void _writeOut(BytecodeContext bc) throws BytecodeException {
    boolean old;

    switch(type) {
    case TYPE_COLLECTION:
      writeOutTypeCollection(bc);
    break;
    case TYPE_CONDITION:
      writeOutTypeCondition(bc);
    break;
    case TYPE_FILE:
      writeOutTypeFile(bc);
    break;
    case TYPE_INDEX:
      writeOutTypeIndex(bc);
    break;
    case TYPE_LIST:
      writeOutTypeListArray(bc,false);
    break;
    case TYPE_ARRAY:
      writeOutTypeListArray(bc,true);
    break;
    case TYPE_QUERY:
      old = bc.changeDoSubFunctions(false);
      TagGroupUtil.writeOutTypeQuery(this,bc);
      bc.changeDoSubFunctions(old);
      //writeOutTypeQuery(bc);
    break;
   
    case TYPE_GROUP:
      old = bc.changeDoSubFunctions(false);
      TagGroupUtil.writeOutTypeGroup(this,bc);
      bc.changeDoSubFunctions(old);
      //writeOutTypeQuery(bc);
    break;
   
    case TYPE_INNER_GROUP:
      old = bc.changeDoSubFunctions(false);
      TagGroupUtil.writeOutTypeInnerGroup(this,bc);
      bc.changeDoSubFunctions(old);
    break;

    case TYPE_INNER_QUERY:
      old = bc.changeDoSubFunctions(false);
      TagGroupUtil.writeOutTypeInnerQuery(this,bc);
      bc.changeDoSubFunctions(old);
    break;
    case TYPE_NOTHING:
      GeneratorAdapter a = bc.getAdapter();
      DoWhileVisitor dwv=new DoWhileVisitor();
      setLoopVisitor(dwv);
      dwv.visitBeginBody(a);
        getBody().writeOut(bc);
      dwv.visitEndBodyBeginExpr(a);
        a.push(false);
      dwv.visitEndExpr(a);
     
     
    break;
   
   
   
    default:
      throw new BytecodeException("invalid type",getStart());
    }
  }

  /**
   * write out collection loop
   * @param adapter
   * @throws TemplateException
   */
  private void writeOutTypeCollection(BytecodeContext bc) throws BytecodeException {
   
    GeneratorAdapter adapter = bc.getAdapter();

    //VariableReference item=VariableInterpreter.getVariableReference(pc,index);
    int index = -1;
    Attribute attrIndex = getAttribute("index");
    if(attrIndex!=null){
      index = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrIndex.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(index);
    }

    //VariableReference item=VariableInterpreter.getVariableReference(pc,item);
    int item = -1;
    Attribute attrItem = getAttribute("item");
    if(attrItem!=null){
      item = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrItem.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(item);
    }
    boolean hasIndexAndItem=index!=-1 && item!=-1;
   
   
   
    WhileVisitor whileVisitor = new WhileVisitor();
    loopVisitor=whileVisitor;
    // java.util.Iterator it=Caster.toIterator(@collection');
    int it=adapter.newLocal(Types.ITERATOR);
    getAttribute("collection").getValue().writeOut(bc,Expression.MODE_REF);
   
    // item and index
    int entry=-1;
    if(hasIndexAndItem) {
      entry = adapter.newLocal(Types.MAP_ENTRY);
      // Caster.toCollection(collection)
      adapter.invokeStatic(Types.CASTER,Methods_Caster.TO_COLLECTION);
      //coll.entryIterator();
      adapter.invokeInterface(Types.COLLECTION, ENTRY_ITERATOR);
    }
    else {
      adapter.invokeStatic(Types.CASTER,ForEach.TO_ITERATOR);
    }
   
   
    adapter.storeLocal(it);
   

   
   
    // while(it.hasNext()) {
    whileVisitor.visitBeforeExpression(bc);
      adapter.loadLocal(it);
      adapter.invokeInterface(Types.ITERATOR, HAS_NEXT);
   
    whileVisitor.visitAfterExpressionBeforeBody(bc);
      if(hasIndexAndItem) {
        // entry=it.next();
        adapter.loadLocal(it);
        adapter.invokeInterface(Types.ITERATOR, NEXT);
        adapter.storeLocal(entry);

        // keyRef.set(pc,entry.getKey())
        adapter.loadLocal(index);
        adapter.loadArg(0);
        adapter.loadLocal(entry);
        adapter.invokeInterface(Types.MAP_ENTRY, GET_KEY);
        adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_STRING);
        adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
        adapter.pop();

        // valueRef.set(pc,entry.getKey())
        adapter.loadLocal(item);
        adapter.loadArg(0);
        adapter.loadLocal(entry);
        adapter.invokeInterface(Types.MAP_ENTRY, GET_VALUE);
        adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
        adapter.pop();
   
      }
      else {
        if(index==-1) adapter.loadLocal(item);
        else adapter.loadLocal(index);
       
        adapter.loadArg(0);
        adapter.loadLocal(it);
        adapter.invokeInterface(Types.ITERATOR, NEXT);
       
        adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
        adapter.pop();
      }
     
     
     
     
     
     
      getBody().writeOut(bc);
    whileVisitor.visitAfterBody(bc,getEnd());
   
  }

  /**
   * write out condition loop
   * @param adapter
   * @throws TemplateException
   */
  private void writeOutTypeCondition(BytecodeContext bc) throws BytecodeException {
    WhileVisitor whileVisitor = new WhileVisitor();
    loopVisitor=whileVisitor;
    whileVisitor.visitBeforeExpression(bc);
      CastBoolean.toExprBoolean(getAttribute("condition").getValue()).writeOut(bc, Expression.MODE_VALUE);
    whileVisitor.visitAfterExpressionBeforeBody(bc);
      getBody().writeOut(bc);
    whileVisitor.visitAfterBody(bc,getEnd());
   
  }
 
  /**
   * write out file loop
   * @param adapter
   * @throws TemplateException
   */
  private void writeOutTypeFile(BytecodeContext bc) throws BytecodeException {
    WhileVisitor whileVisitor = new WhileVisitor();
    loopVisitor=whileVisitor;
    GeneratorAdapter adapter = bc.getAdapter();
   
    // charset=@charset
    int charset=adapter.newLocal(Types.STRING);
    Attribute attrCharset = getAttribute("charset");
    if(attrCharset==null) adapter.visitInsn(Opcodes.ACONST_NULL);
    else attrCharset.getValue().writeOut(bc, Expression.MODE_REF);
    adapter.storeLocal(charset);
   
    // startline=@startline
    int startline=adapter.newLocal(Types.INT_VALUE);
    Attribute attrStartLine = getAttribute("startline");
    if(attrStartLine==null) attrStartLine = getAttribute("from"); // CF8
    if(attrStartLine==null) adapter.push(1);
    else {
      attrStartLine.getValue().writeOut(bc, Expression.MODE_VALUE);
      adapter.visitInsn(Opcodes.D2I);
    }
    adapter.storeLocal(startline);
   
    // endline=@endline
    int endline=adapter.newLocal(Types.INT_VALUE);
    Attribute attrEndLine = getAttribute("endline");
    if(attrEndLine==null) attrEndLine = getAttribute("to");
    if(attrEndLine==null) adapter.push(-1);
    else {
      attrEndLine.getValue().writeOut(bc, Expression.MODE_VALUE);
      adapter.visitInsn(Opcodes.D2I);
    }
    adapter.storeLocal(endline);

   
    //VariableReference index=VariableInterpreter.getVariableReference(pc,@index);
    int index=-1,item=-1;
   
    // item
    Attribute attrItem = getAttribute("item");
    if(attrItem!=null) {
      item = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrItem.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(item);
    }

    // index
    Attribute attrIndex = getAttribute("index");
    if(attrIndex!=null) {
      index = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrIndex.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(index);
    }
   
    //java.io.File file=FileUtil.toResourceExisting(pc,@file);
    int resource=adapter.newLocal(Types.RESOURCE);
    adapter.loadArg(0);
    getAttribute("file").getValue().writeOut(bc, Expression.MODE_REF);
    adapter.invokeStatic(RESOURCE_UTIL, TO_RESOURCE_EXISTING);
    adapter.storeLocal(resource);
   
    // pc.getConfig().getSecurityManager().checkFileLocation(resource);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_CONFIG);
    adapter.invokeInterface(Types.CONFIG_WEB, GET_SECURITY_MANAGER);
    adapter.loadLocal(resource);
    adapter.invokeInterface(Types.SECURITY_MANAGER, CHECK_FILE_LOCATION);
   
    // char[] carr=new char[characters];
    Attribute attr = getAttribute("characters");
    int carr=-1;
    if(attr!=null) {
      carr=adapter.newLocal(Types.CHAR_ARRAY);
      attr.getValue().writeOut(bc, Expression.MODE_VALUE);
      adapter.cast(Types.DOUBLE_VALUE, Types.INT_VALUE);
      adapter.newArray(Types.CHAR);
      adapter.storeLocal(carr);
    }
   
    // BufferedReader reader = IOUtil.getBufferedReader(resource,charset);
    final int br=adapter.newLocal(Types.BUFFERED_READER);
    adapter.loadLocal(resource);
    adapter.loadLocal(charset);
    adapter.invokeStatic(IO_UTIL, GET_BUFFERED_READER);
    adapter.storeLocal(br);
   
    // String line;
    int line=adapter.newLocal(Types.STRING);
   
    // int count=0; 
    int count=adapter.newLocal(Types.INT_VALUE);
    adapter.push(0);
    adapter.storeLocal(count);
   
    TryFinallyVisitor tfv=new TryFinallyVisitor(new OnFinally() {
      public void writeOut(BytecodeContext bc) {
        bc.getAdapter().loadLocal(br);
        bc.getAdapter().invokeStatic(IO_UTIL, CLOSE_EL);
      }
    },null);
    //TryFinallyVisitor tcfv=new TryFinallyVisitor();
   
    // try
    tfv.visitTryBegin(bc);
    //tcfv.visitTryBegin(bc);
      // while((line=br.readLine())!=null) {
      //WhileVisitor wv=new WhileVisitor();
      whileVisitor.visitBeforeExpression(bc);
        DecisionObjectVisitor dv=new DecisionObjectVisitor();
        dv.visitBegin();
          if(attr!=null) {
            // IOUtil.read(bufferedreader,12)
            adapter.loadLocal(br);
            adapter.loadLocal(carr);
            adapter.arrayLength();
            adapter.invokeStatic(Types.IOUTIL, READ);
          }
          else {
            // br.readLine()
            adapter.loadLocal(br);
            adapter.invokeVirtual(Types.BUFFERED_READER, READ_LINE);
          }
          adapter.dup();
          adapter.storeLocal(line);
         
        dv.visitNEQ();
          adapter.visitInsn(Opcodes.ACONST_NULL);
        dv.visitEnd(bc);
       
      whileVisitor.visitAfterExpressionBeforeBody(bc);
        //if(++count < startLine) continue;
        DecisionIntVisitor dv2=new DecisionIntVisitor();
        dv2.visitBegin();
          adapter.iinc(count, 1);
          adapter.loadLocal(count);
        dv2.visitLT();
          adapter.loadLocal(startline);
        dv2.visitEnd(bc);
        Label end=new Label();
        adapter.ifZCmp(Opcodes.IFEQ, end);
          whileVisitor.visitContinue(bc);
        adapter.visitLabel(end);
       
        // if(endLine!=-1 && count > endLine) break;
        DecisionIntVisitor div=new DecisionIntVisitor();
        div.visitBegin();
          adapter.loadLocal(endline);
        div.visitNEQ();
          adapter.push(-1);
        div.visitEnd(bc);
        Label end2=new Label();
        adapter.ifZCmp(Opcodes.IFEQ, end2);
       
          DecisionIntVisitor div2 = new DecisionIntVisitor();
          div2.visitBegin();
            adapter.loadLocal(count);
          div2.visitGT();
            adapter.loadLocal(endline);
          div2.visitEnd(bc);
          Label end3=new Label();
          adapter.ifZCmp(Opcodes.IFEQ, end3);
            whileVisitor.visitBreak(bc);
          adapter.visitLabel(end3);
        adapter.visitLabel(end2);
       
        // index and item
        if(index!=-1 && item!=-1) {
          // index.set(pc,line);
          adapter.loadLocal(index);
          adapter.loadArg(0);
          adapter.loadLocal(count);
          adapter.cast(Types.INT_VALUE,Types.DOUBLE_VALUE);
          adapter.invokeStatic(Types.CASTER, Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
         
          adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
          adapter.pop();
         
          // item.set(pc,line);
          adapter.loadLocal(item);
          adapter.loadArg(0);
          adapter.loadLocal(line);
          adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
          adapter.pop();
         
        }
        // only index
        else if(index!=-1) {
          // index.set(pc,line);
          adapter.loadLocal(index);
          adapter.loadArg(0);
          adapter.loadLocal(line);
          adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
          adapter.pop();
         
        }
        // only item
        else {
          // item.set(pc,line);
          adapter.loadLocal(item);
          adapter.loadArg(0);
          adapter.loadLocal(line);
          adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
          adapter.pop();
        }
       
       
       
       
        getBody().writeOut(bc);
       
      whileVisitor.visitAfterBody(bc,getEnd());
     
    tfv.visitTryEnd(bc);
   
  }

  /**
   * write out index loop
   * @param adapter
   * @throws TemplateException
   */
  private void writeOutTypeIndex(BytecodeContext bc) throws BytecodeException {
    ForDoubleVisitor forDoubleVisitor = new ForDoubleVisitor();
    loopVisitor=forDoubleVisitor;
    GeneratorAdapter adapter = bc.getAdapter();

    // int from=(int)@from;
    int from=adapter.newLocal(Types.DOUBLE_VALUE);
    ExpressionUtil.writeOutSilent(getAttribute("from").getValue(), bc, Expression.MODE_VALUE);
    adapter.storeLocal(from)
   
    // int to=(int)@to;
    int to=adapter.newLocal(Types.DOUBLE_VALUE);
    ExpressionUtil.writeOutSilent(getAttribute("to").getValue(), bc, Expression.MODE_VALUE);
    adapter.storeLocal(to)
   
    // int step=(int)@step;
    int step=adapter.newLocal(Types.DOUBLE_VALUE);
    Attribute attrStep = getAttribute("step");
    if(attrStep!=null) {
      ExpressionUtil.writeOutSilent(attrStep.getValue(), bc, Expression.MODE_VALUE);
    }
    else {
      adapter.push(1D);
    }
    adapter.storeLocal(step);
   
    // boolean dirPlus=(step > 0);
    int dirPlus=adapter.newLocal(Types.BOOLEAN_VALUE);
    DecisionDoubleVisitor div=new DecisionDoubleVisitor();
    div.visitBegin();
      adapter.loadLocal(step);
    div.visitGT();
      adapter.push(0D);
    div.visitEnd(bc);
    adapter.storeLocal(dirPlus);
   
    //if(step!=0) {
    div=new DecisionDoubleVisitor();
    div.visitBegin();
      adapter.loadLocal(step);
    div.visitNEQ();
      adapter.push(0D);
    div.visitEnd(bc);
    Label ifEnd=new Label();
    adapter.ifZCmp(Opcodes.IFEQ, ifEnd);
     
      // VariableReference index>=VariableInterpreter.getVariableReference(pc,@index));
      int index = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      ExpressionUtil.writeOutSilent(getAttribute("index").getValue(), bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(index);
     

      // index.set(from);
      adapter.loadLocal(index);
      adapter.loadLocal(from);
      adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET_DOUBLE);
     
      // for
       
      //int i=forConditionVisitor.visitBeforeExpression(adapter,from,step,true);
     
      // init
      adapter.visitLabel(forDoubleVisitor.beforeInit);
      forDoubleVisitor.forInit(adapter, from, true);
      adapter.goTo(forDoubleVisitor.beforeExpr);
     
      // update
      adapter.visitLabel(forDoubleVisitor.beforeUpdate);
      adapter.loadLocal(index);
      //forConditionVisitor.forUpdate(adapter, step, true);
      adapter.visitVarInsn(Opcodes.DLOAD, forDoubleVisitor.i);
      adapter.loadLocal(step);
      adapter.visitInsn(Opcodes.DADD);
      adapter.visitInsn(Opcodes.DUP2);
      adapter.visitVarInsn(Opcodes.DSTORE, forDoubleVisitor.i);
     
     
     
      adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET_DOUBLE);
     
     
     
     
      // expression
      adapter.visitLabel(forDoubleVisitor.beforeExpr);
      int i=forDoubleVisitor.i;
     
     
     
     
     
        adapter.loadLocal(dirPlus);
        Label l1 = new Label();
        adapter.visitJumpInsn(Opcodes.IFEQ, l1);
       
          div=new DecisionDoubleVisitor();
          div.visitBegin();
            adapter.visitVarInsn(Opcodes.DLOAD, i);
          div.visitLTE();
            adapter.loadLocal(to);
          div.visitEnd(bc);
         
        Label l2 = new Label();
        adapter.visitJumpInsn(Opcodes.GOTO, l2);
        adapter.visitLabel(l1);
       
          div=new DecisionDoubleVisitor();
          div.visitBegin();
            adapter.visitVarInsn(Opcodes.DLOAD, i);
          div.visitGTE();
            adapter.loadLocal(to);
          div.visitEnd(bc);
       
        adapter.visitLabel(l2);
      forDoubleVisitor.visitAfterExpressionBeginBody(adapter);
       
        //adapter.loadLocal(index);
        //adapter.visitVarInsn(Opcodes.DLOAD, i);
        //adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET_DOUBLE);
       
        getBody().writeOut(bc);
     
      forDoubleVisitor.visitEndBody(bc,getEnd());
       
     
     
      ////// set i after usage
      //adapter.loadLocal(index);
      //adapter.visitVarInsn(Opcodes.DLOAD, i);
      //adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET_DOUBLE);
     
    adapter.visitLabel(ifEnd);
   
  }
 
  /**
   * write out list loop
   * @param adapter
   * @throws TemplateException
   */
  private void writeOutTypeListArray(BytecodeContext bc, boolean isArray) throws BytecodeException {
    ForVisitor forVisitor = new ForVisitor();
    loopVisitor=forVisitor;
    GeneratorAdapter adapter = bc.getAdapter();

    //List.listToArrayRemoveEmpty("", 'c')
    int array = adapter.newLocal(Types.ARRAY);
    int len = adapter.newLocal(Types.INT_VALUE);
   
    if(isArray) {
      getAttribute("array").getValue().writeOut(bc, Expression.MODE_REF);
    }
    else {
      // array=List.listToArrayRemoveEmpty(list, delimter)
      getAttribute("list").getValue().writeOut(bc, Expression.MODE_REF);
      if(containsAttribute("delimiters")) {
        getAttribute("delimiters").getValue().writeOut(bc, Expression.MODE_REF);
        adapter.invokeStatic(Types.LIST_UTIL, LIST_TO_ARRAY_REMOVE_EMPTY_SS);
      }
      else {
        adapter.visitIntInsn(Opcodes.BIPUSH, 44);// ','
        //adapter.push(',');
        adapter.invokeStatic(Types.LIST_UTIL, LIST_TO_ARRAY_REMOVE_EMPTY_SC);
      }
    }
    adapter.storeLocal(array);
 
   
    // int len=array.size();
    adapter.loadLocal(array);
    adapter.invokeInterface(Types.ARRAY, SIZE);
    adapter.storeLocal(len);

   
    //VariableInterpreter.getVariableReference(pc,Caster.toString(index));
    Attribute attrIndex = getAttribute("index");
    int index = -1;
    if(attrIndex!=null) {
      index = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrIndex.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(index);
    }
   

    //VariableInterpreter.getVariableReference(pc,Caster.toString(item));
    Attribute attrItem = getAttribute("item");
    int item = -1;
    if(attrItem!=null) {
      item = adapter.newLocal(Types.VARIABLE_REFERENCE);
      adapter.loadArg(0);
      attrItem.getValue().writeOut(bc, Expression.MODE_REF);
      adapter.invokeStatic(Types.VARIABLE_INTERPRETER, GET_VARIABLE_REFERENCE);
      adapter.storeLocal(item);
    }
   
   
    int obj=0;
    if(isArray)obj=adapter.newLocal(Types.OBJECT);
   
    // for(int i=1;i<=len;i++) {   
    int i = forVisitor.visitBegin(adapter, 1, false);
      // index.set(pc, list.get(i));
     
      if(isArray) {
       
       
        // value
        adapter.loadLocal(array);
        adapter.visitVarInsn(Opcodes.ILOAD, i);
        ASMConstants.NULL(adapter);
        adapter.invokeInterface(Types.ARRAY, GET);
        adapter.dup();
        adapter.storeLocal(obj);
        Label endIf=new Label();
        //adapter.loadLocal(obj);
        adapter.visitJumpInsn(Opcodes.IFNONNULL, endIf);
          adapter.goTo(forVisitor.getContinueLabel());
        adapter.visitLabel(endIf);
       
       
        if(item==-1) adapter.loadLocal(index);
        else adapter.loadLocal(item);
       
        adapter.loadArg(0);
       
       
        adapter.loadLocal(obj);
       
      }
      else {
        if(item==-1) adapter.loadLocal(index);
        else adapter.loadLocal(item);
        adapter.loadArg(0);
          adapter.loadLocal(array);
          adapter.visitVarInsn(Opcodes.ILOAD, i);
          adapter.invokeInterface(Types.ARRAY, GETE);
         
       
      }
      adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
      adapter.pop();
     

      // key
      if(index!=-1 && item!=-1) {
        adapter.loadLocal(index);
        adapter.loadArg(0);
        adapter.visitVarInsn(Opcodes.ILOAD, i);
        adapter.cast(Types.INT_VALUE,Types.DOUBLE_VALUE);
              adapter.invokeStatic(Types.CASTER,Methods_Caster.TO_DOUBLE[Methods_Caster.DOUBLE]);
              adapter.invokeVirtual(Types.VARIABLE_REFERENCE, SET);
        adapter.pop();
      }
     
     
      getBody().writeOut(bc);
    forVisitor.visitEnd(bc, len, true,getStart());
  }
 
  /* *
   * write out query loop
   * @param adapter
   * @throws TemplateException
   * /
  private void writeOutTypeQuery(BytecodeContext bc) throws BytecodeException {
    ForConditionIntVisitor forConditionVisitor = new ForConditionIntVisitor();// TODO replace with ForIntVisitor
    loopVisitor=forConditionVisitor;
    final GeneratorAdapter adapter = bc.getAdapter();

    // railo.runtime.type.Query query=pc.getQuery(@query);
    final int query=adapter.newLocal(Types.QUERY);
    adapter.loadArg(0);
    Expression val = getAttribute("query").getValue();
    val.writeOut(bc, Expression.MODE_REF);
    if(val instanceof LitString)
      adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_QUERY_STRING);
    else
      adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_QUERY_OBJ);
    //adapter.dup();
    adapter.storeLocal(query);
   
    //int queryImpl = adapter.newLocal(Types.QUERY_IMPL);
    //adapter.checkCast(Types.QUERY_IMPL);
    //adapter.storeLocal(queryImpl);
   
   
    // int startAt=query.getCurrentrow();
    final int startAt=adapter.newLocal(Types.INT_VALUE);
   
    adapter.loadLocal(query);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID);
    adapter.invokeInterface(Types.QUERY, GET_CURRENTROW_1);
    adapter.storeLocal(startAt);
   
   
    // startrow
    int start=adapter.newLocal(Types.INT_VALUE);
    Attribute attrStartRow = getAttribute("startrow");
    if(attrStartRow!=null){
      //railo.runtime.util.NumberRange.range(@startrow,1)
      attrStartRow.getValue().writeOut(bc, Expression.MODE_VALUE);
      adapter.push(1d);
      adapter.invokeStatic(Types.NUMBER_RANGE, RANGE);
      adapter.visitInsn(Opcodes.D2I);
    }
    else {
      adapter.push(1);
    }
    adapter.storeLocal(start);
   
    // endrow
    int end=adapter.newLocal(Types.INT_VALUE);
    Attribute attrEndRow = getAttribute("endrow");
    if(attrEndRow!=null){
      attrEndRow.getValue().writeOut(bc, Expression.MODE_VALUE);
      adapter.visitInsn(Opcodes.D2I);
      adapter.storeLocal(end);
    }
   
    // pc.us().addQuery(query);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, US);
    adapter.loadLocal(query);
    adapter.invokeInterface(UNDEFINED, ADD_QUERY);
   
    // try
    TryFinallyVisitor tfv=new TryFinallyVisitor(new OnFinally() {
      public void writeOut(BytecodeContext bc) {
        //GeneratorAdapter ga = bc.getAdapter();
        // pc.us().removeCollection();
        adapter.loadArg(0);
        adapter.invokeVirtual(Types.PAGE_CONTEXT, US);
        adapter.invokeInterface(UNDEFINED, REMOVE_QUERY);
     
        // query.go(startAt);
        adapter.loadLocal(query);
        adapter.loadLocal(startAt);
       
        adapter.loadArg(0);
        adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID);
        adapter.invokeInterface(Types.QUERY, GO);
        adapter.pop();
      }
    });
    tfv.visitTryBegin(bc);
      // For
     
      int i=forConditionVisitor.visitBegin(adapter, start, true);
        getBody().writeOut(bc);
      forConditionVisitor.visitEndBeforeCondition(bc,1,false,getStart());
       
        // && i<=endrow
        if(attrEndRow!=null){
          AndVisitor av=new AndVisitor();
          av.visitBegin();
            adapter.loadLocal(query);
            adapter.visitVarInsn(Opcodes.ILOAD, i);
           
            adapter.loadArg(0);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID);
            adapter.invokeInterface(Types.QUERY, GO);
           
          av.visitMiddle(bc);
            //LitBoolean.TRUE.writeOut(bc, Expression.MODE_VALUE);
            DecisionIntVisitor dv=new DecisionIntVisitor();
            dv.visitBegin();
              adapter.visitVarInsn(Opcodes.ILOAD, i);
            dv.visitLTE();
              adapter.loadLocal(end);
            dv.visitEnd(bc);
          av.visitEnd(bc);
        }
        else {
          adapter.loadLocal(query);
          adapter.visitVarInsn(Opcodes.ILOAD, i);
         
          adapter.loadArg(0);
          adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID);
          adapter.invokeInterface(Types.QUERY, GO);
         
       
        }
       
       
      forConditionVisitor.visitEndAfterCondition(bc);

    // Finally
    tfv.visitTryEnd(bc);
  }*/

  /**
   * @see railo.transformer.bytecode.statement.FlowControl#getBreakLabel()
   */
  public Label getBreakLabel() {
    return loopVisitor.getBreakLabel();
  }
 
  /**
   * @see railo.transformer.bytecode.statement.FlowControl#getContinueLabel()
   */
  public Label getContinueLabel() {
    return loopVisitor.getContinueLabel();
  }

  @Override
  public short getType() {
    return TAG_LOOP;
  }

  public void setLoopVisitor(LoopVisitor loopVisitor) {
    this.loopVisitor=loopVisitor;
  }

  @Override
  public FlowControlFinal getFlowControlFinal() {
    return null;
  }

  public void setLabel(String label) {
    this.label=label;
  }

  @Override
  public String getLabel() {
    return label;
  }
}
TOP

Related Classes of railo.transformer.bytecode.statement.tag.TagLoop

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.