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