001 package railo.transformer.bytecode.cast; 002 003 import org.objectweb.asm.Type; 004 import org.objectweb.asm.commons.GeneratorAdapter; 005 import org.objectweb.asm.commons.Method; 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.expression.ExprBoolean; 012 import railo.transformer.bytecode.expression.ExprDouble; 013 import railo.transformer.bytecode.expression.ExprFloat; 014 import railo.transformer.bytecode.expression.ExprString; 015 import railo.transformer.bytecode.expression.Expression; 016 import railo.transformer.bytecode.expression.ExpressionBase; 017 import railo.transformer.bytecode.literal.LitFloat; 018 import railo.transformer.bytecode.op.OpDouble; 019 import railo.transformer.bytecode.util.Methods; 020 import railo.transformer.bytecode.util.Types; 021 022 /** 023 * cast a Expression to a Double 024 */ 025 public final class CastFloat extends ExpressionBase implements ExprFloat,Cast { 026 027 private Expression expr; 028 029 private CastFloat(Expression expr) { 030 super(expr.getStart(),expr.getEnd()); 031 this.expr=expr; 032 } 033 034 /** 035 * Create a String expression from a Expression 036 * @param expr 037 * @return String expression 038 * @throws TemplateException 039 */ 040 public static ExprFloat toExprFloat(Expression expr) { 041 if(expr instanceof ExprFloat) return (ExprFloat) expr; 042 if(expr instanceof Literal) { 043 Double dbl = ((Literal)expr).getDouble(null); 044 if(dbl!=null) return new LitFloat((float)dbl.doubleValue(),expr.getStart(),expr.getEnd()); 045 } 046 return new CastFloat(expr); 047 } 048 049 /** 050 * @see railo.transformer.bytecode.expression.Expression#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 051 */ 052 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 053 054 GeneratorAdapter adapter = bc.getAdapter(); 055 056 if(expr instanceof OpDouble) { 057 ((OpDouble)expr).writeOutDouble(bc,MODE_VALUE); 058 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 059 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 060 } 061 else if(expr instanceof ExprBoolean) { 062 expr.writeOut(bc,MODE_VALUE); 063 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 064 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 065 066 } 067 else if(expr instanceof ExprFloat) { 068 expr.writeOut(bc,mode); 069 } 070 else if(expr instanceof ExprDouble) { 071 expr.writeOut(bc,MODE_VALUE); 072 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 073 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 074 } 075 else if(expr instanceof ExprString) { 076 expr.writeOut(bc,MODE_REF); 077 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_STRING); 078 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_STRING); 079 } 080 else { 081 Type rtn = expr.writeOut(bc,mode); 082 if(mode==MODE_VALUE) { 083 if(!Types.isPrimitiveType(rtn)) { 084 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 085 } 086 else if(Types.DOUBLE_VALUE.equals(rtn)) { 087 adapter.cast(Types.DOUBLE_VALUE, Types.FLOAT_VALUE); 088 } 089 else if(Types.FLOAT_VALUE.equals(rtn)) {} 090 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 091 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 092 } 093 else { 094 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 095 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 096 } 097 return Types.FLOAT_VALUE; 098 } 099 else if(Types.isPrimitiveType(rtn)) { 100 if(Types.DOUBLE_VALUE.equals(rtn)) { 101 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 102 } 103 else if(Types.FLOAT_VALUE.equals(rtn)) { 104 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_FLOAT); 105 } 106 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 107 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 108 } 109 else { 110 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 111 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 112 } 113 return Types.FLOAT; 114 } 115 //else { 116 if(!Types.FLOAT.equals(rtn)) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 117 return Types.FLOAT; 118 //} 119 } 120 121 122 if(mode==MODE_VALUE)return Types.FLOAT_VALUE; 123 return Types.FLOAT; 124 } 125 126 @Override 127 public Expression getExpr() { 128 return expr; 129 } 130 } 131 132 133 134