001 package railo.transformer.bytecode.op; 002 003 import org.objectweb.asm.Opcodes; 004 import org.objectweb.asm.Type; 005 import org.objectweb.asm.commons.GeneratorAdapter; 006 007 import railo.runtime.exp.TemplateException; 008 import railo.transformer.bytecode.BytecodeContext; 009 import railo.transformer.bytecode.BytecodeException; 010 import railo.transformer.bytecode.Literal; 011 import railo.transformer.bytecode.Position; 012 import railo.transformer.bytecode.cast.CastDouble; 013 import railo.transformer.bytecode.expression.ExprDouble; 014 import railo.transformer.bytecode.expression.Expression; 015 import railo.transformer.bytecode.expression.ExpressionBase; 016 import railo.transformer.bytecode.literal.LitDouble; 017 import railo.transformer.bytecode.util.Methods; 018 import railo.transformer.bytecode.util.Types; 019 020 public final class OpNegateNumber extends ExpressionBase implements ExprDouble { 021 022 private ExprDouble expr; 023 024 025 public static final int PLUS = 0; 026 public static final int MINUS = 1; 027 028 private OpNegateNumber(Expression expr, Position start, Position end) { 029 super(start,end); 030 this.expr=CastDouble.toExprDouble(expr); 031 } 032 033 /** 034 * Create a String expression from a Expression 035 * @param left 036 * @param right 037 * 038 * @return String expression 039 * @throws TemplateException 040 */ 041 public static ExprDouble toExprDouble(Expression expr, Position start, Position end) { 042 if(expr instanceof Literal) { 043 Double d=((Literal) expr).getDouble(null); 044 if(d!=null) { 045 return LitDouble.toExprDouble(-d.doubleValue(),start,end); 046 } 047 } 048 return new OpNegateNumber(expr,start,end); 049 } 050 051 public static ExprDouble toExprDouble(Expression expr, int operation, Position start, Position end) { 052 if(operation==MINUS) return toExprDouble(expr, start,end); 053 return CastDouble.toExprDouble(expr); 054 } 055 056 057 /** 058 * 059 * @see railo.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 060 */ 061 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 062 GeneratorAdapter adapter = bc.getAdapter(); 063 if(mode==MODE_REF) { 064 _writeOut(bc,MODE_VALUE); 065 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE); 066 return Types.DOUBLE; 067 } 068 069 expr.writeOut(bc, MODE_VALUE); 070 adapter.visitInsn(Opcodes.DNEG); 071 072 073 return Types.DOUBLE_VALUE; 074 } 075 }