001 package railo.transformer.bytecode.statement.java; 002 003 import org.objectweb.asm.Type; 004 import org.objectweb.asm.commons.GeneratorAdapter; 005 006 import railo.transformer.bytecode.BytecodeContext; 007 import railo.transformer.bytecode.BytecodeException; 008 import railo.transformer.bytecode.expression.ExpressionBase; 009 import railo.transformer.bytecode.util.Types; 010 011 public class Operation extends ExpressionBase { 012 013 private Object left; 014 private Object right; 015 private DataBag db; 016 private int op; 017 018 public Operation(int line,Object left, Object right,String operation, DataBag db) { 019 super(line); 020 this.left=left; 021 this.right=right; 022 this.db = db; 023 024 if("plus".equals(operation))this.op=GeneratorAdapter.ADD; 025 else if("minus".equals(operation))this.op=GeneratorAdapter.SUB; 026 else if("divide".equals(operation))this.op=GeneratorAdapter.DIV; 027 else if("slash".equals(operation))this.op=GeneratorAdapter.DIV; 028 else if("star".equals(operation))this.op=GeneratorAdapter.MUL; 029 else if("times".equals(operation))this.op=GeneratorAdapter.MUL; 030 else if("rem".equals(operation))this.op=GeneratorAdapter.REM; 031 else if("remainder".equals(operation))this.op=GeneratorAdapter.REM; 032 else if("binAnd".equals(operation))this.op=GeneratorAdapter.AND; 033 else if("and".equals(operation))this.op=GeneratorAdapter.AND; 034 else if("binOr".equals(operation))this.op=GeneratorAdapter.OR; 035 else if("or".equals(operation))this.op=GeneratorAdapter.OR; 036 else throw new RuntimeException("invalid operator ["+operation+"]"); 037 038 } 039 040 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 041 Type l = Assign.writeOut(db,bc,null,mode,left,getLine(),false); 042 Type r = Assign.writeOut(db,bc,null,mode,right,getLine(),false); 043 Type t = result(l,r); 044 045 bc.getAdapter().math(op,t); 046 047 return t; 048 } 049 050 public static Type result(Type left, Type right) { 051 if(left==Types.DOUBLE_VALUE || right==Types.DOUBLE_VALUE) return Types.DOUBLE_VALUE; 052 if(left==Types.FLOAT_VALUE || right==Types.FLOAT_VALUE) return Types.FLOAT_VALUE; 053 if(left==Types.LONG_VALUE || right==Types.LONG_VALUE) return Types.LONG_VALUE; 054 if(left==Types.INT_VALUE || right==Types.INT_VALUE) return Types.INT_VALUE; 055 if(left==Types.SHORT_VALUE || right==Types.SHORT_VALUE) return Types.SHORT_VALUE; 056 057 return Types.CHAR; 058 } 059 060 public static void dup(BytecodeContext bc, Type t) { 061 String cn=t.getClassName(); 062 if(cn.equals("long") || cn.equals("double")) bc.getAdapter().dup2(); 063 else bc.getAdapter().dup(); 064 } 065 066 }