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 UnaryOp extends ExpressionBase { 012 013 private DataBag db; 014 private Object operant; 015 private String operation; 016 017 public UnaryOp(int line,Object operant, String operation, DataBag db) { 018 super(line); 019 this.operant=operant; 020 this.operation=operation; 021 this.db = db; 022 } 023 024 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 025 026 Integer var=db.locals.get(operant); 027 if(var==null) 028 throw new BytecodeException("there is no variable with name ["+operation+"] in the enviroment", getLine()); 029 030 GeneratorAdapter a = bc.getAdapter(); 031 032 if(operation.startsWith("pos")) a.loadLocal(var.intValue()); 033 if("preDecrement".equals(operation))a.iinc(var.intValue(), -1); 034 else if("posDecrement".equals(operation))a.iinc(var.intValue(), -1); 035 else if("preIncrement".equals(operation))a.iinc(var.intValue(), 1); 036 else if("posIncrement".equals(operation))a.iinc(var.intValue(), 1); 037 if(operation.startsWith("pre")) a.loadLocal(var.intValue()); 038 039 return a.getLocalType(var.intValue()); 040 } 041 042 public static Type result(Type left, Type right) { 043 if(left==Types.DOUBLE_VALUE || right==Types.DOUBLE_VALUE) return Types.DOUBLE_VALUE; 044 if(left==Types.FLOAT_VALUE || right==Types.FLOAT_VALUE) return Types.FLOAT_VALUE; 045 if(left==Types.LONG_VALUE || right==Types.LONG_VALUE) return Types.LONG_VALUE; 046 if(left==Types.INT_VALUE || right==Types.INT_VALUE) return Types.INT_VALUE; 047 if(left==Types.SHORT_VALUE || right==Types.SHORT_VALUE) return Types.SHORT_VALUE; 048 049 return Types.CHAR; 050 } 051 052 public static void dup(BytecodeContext bc, Type t) { 053 String cn=t.getClassName(); 054 if(cn.equals("long") || cn.equals("double")) bc.getAdapter().dup2(); 055 else bc.getAdapter().dup(); 056 } 057 058 059 060 }