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 { 026 027 private Expression expr; 028 029 private CastFloat(Expression expr) { 030 super(expr.getLine()); 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.getLine()); 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_REF)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_FLOAT); 059 } 060 else if(expr instanceof ExprBoolean) { 061 expr.writeOut(bc,MODE_VALUE); 062 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 063 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 064 065 } 066 else if(expr instanceof ExprFloat) { 067 expr.writeOut(bc,mode); 068 //if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 069 //if(mode==MODE_REF) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_FLOAT); 070 } 071 else if(expr instanceof ExprDouble) { 072 expr.writeOut(bc,MODE_VALUE); 073 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 074 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 075 } 076 else if(expr instanceof ExprString) { 077 expr.writeOut(bc,MODE_REF); 078 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_STRING); 079 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_STRING); 080 } 081 else { 082 Type rtn = expr.writeOut(bc,mode); 083 if(mode==MODE_VALUE) { 084 if(!Types.isPrimitiveType(rtn)) { 085 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 086 } 087 else if(Types.DOUBLE_VALUE.equals(rtn)) { 088 adapter.cast(Types.DOUBLE_VALUE, Types.FLOAT_VALUE); 089 } 090 else if(Types.FLOAT_VALUE.equals(rtn)) {} 091 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 092 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 093 } 094 else { 095 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 096 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 097 } 098 return Types.FLOAT_VALUE; 099 } 100 else if(Types.isPrimitiveType(rtn)) { 101 if(Types.DOUBLE_VALUE.equals(rtn)) { 102 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 103 } 104 else if(Types.FLOAT_VALUE.equals(rtn)) { 105 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_FLOAT); 106 } 107 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 108 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 109 } 110 else { 111 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 112 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 113 } 114 return Types.FLOAT; 115 } 116 //else { 117 if(!Types.FLOAT.equals(rtn)) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 118 return Types.FLOAT; 119 //} 120 } 121 122 123 if(mode==MODE_VALUE)return Types.FLOAT_VALUE; 124 return Types.FLOAT; 125 } 126 127 /* * 128 * @see railo.transformer.bytecode.expression.Expression#getType() 129 * / 130 public int getType() { 131 return Types._DOUBLE; 132 }*/ 133 134 } 135 136 137 138