001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.transformer.bytecode.cast; 020 021import lucee.runtime.exp.TemplateException; 022import lucee.transformer.bytecode.BytecodeContext; 023import lucee.transformer.bytecode.BytecodeException; 024import lucee.transformer.bytecode.Literal; 025import lucee.transformer.bytecode.expression.ExprBoolean; 026import lucee.transformer.bytecode.expression.ExprDouble; 027import lucee.transformer.bytecode.expression.ExprFloat; 028import lucee.transformer.bytecode.expression.ExprString; 029import lucee.transformer.bytecode.expression.Expression; 030import lucee.transformer.bytecode.expression.ExpressionBase; 031import lucee.transformer.bytecode.literal.LitFloat; 032import lucee.transformer.bytecode.op.OpDouble; 033import lucee.transformer.bytecode.util.Methods; 034import lucee.transformer.bytecode.util.Types; 035 036import org.objectweb.asm.Type; 037import org.objectweb.asm.commons.GeneratorAdapter; 038import org.objectweb.asm.commons.Method; 039 040/** 041 * cast a Expression to a Double 042 */ 043public final class CastFloat extends ExpressionBase implements ExprFloat,Cast { 044 045 private Expression expr; 046 047 private CastFloat(Expression expr) { 048 super(expr.getStart(),expr.getEnd()); 049 this.expr=expr; 050 } 051 052 /** 053 * Create a String expression from a Expression 054 * @param expr 055 * @return String expression 056 * @throws TemplateException 057 */ 058 public static ExprFloat toExprFloat(Expression expr) { 059 if(expr instanceof ExprFloat) return (ExprFloat) expr; 060 if(expr instanceof Literal) { 061 Double dbl = ((Literal)expr).getDouble(null); 062 if(dbl!=null) return new LitFloat((float)dbl.doubleValue(),expr.getStart(),expr.getEnd()); 063 } 064 return new CastFloat(expr); 065 } 066 067 /** 068 * @see lucee.transformer.bytecode.expression.Expression#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 069 */ 070 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 071 072 GeneratorAdapter adapter = bc.getAdapter(); 073 074 if(expr instanceof OpDouble) { 075 ((OpDouble)expr).writeOutDouble(bc,MODE_VALUE); 076 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 077 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 078 } 079 else if(expr instanceof ExprBoolean) { 080 expr.writeOut(bc,MODE_VALUE); 081 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 082 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 083 084 } 085 else if(expr instanceof ExprFloat) { 086 expr.writeOut(bc,mode); 087 } 088 else if(expr instanceof ExprDouble) { 089 expr.writeOut(bc,MODE_VALUE); 090 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_DOUBLE); 091 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 092 } 093 else if(expr instanceof ExprString) { 094 expr.writeOut(bc,MODE_REF); 095 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_STRING); 096 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_STRING); 097 } 098 else { 099 Type rtn = expr.writeOut(bc,mode); 100 if(mode==MODE_VALUE) { 101 if(!Types.isPrimitiveType(rtn)) { 102 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 103 } 104 else if(Types.DOUBLE_VALUE.equals(rtn)) { 105 adapter.cast(Types.DOUBLE_VALUE, Types.FLOAT_VALUE); 106 } 107 else if(Types.FLOAT_VALUE.equals(rtn)) {} 108 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 109 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE_FROM_BOOLEAN); 110 } 111 else { 112 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 113 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_VALUE); 114 } 115 return Types.FLOAT_VALUE; 116 } 117 else if(Types.isPrimitiveType(rtn)) { 118 if(Types.DOUBLE_VALUE.equals(rtn)) { 119 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_DOUBLE); 120 } 121 else if(Types.FLOAT_VALUE.equals(rtn)) { 122 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_FLOAT); 123 } 124 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 125 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT_FROM_BOOLEAN); 126 } 127 else { 128 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 129 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 130 } 131 return Types.FLOAT; 132 } 133 //else { 134 if(!Types.FLOAT.equals(rtn)) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_FLOAT); 135 return Types.FLOAT; 136 //} 137 } 138 139 140 if(mode==MODE_VALUE)return Types.FLOAT_VALUE; 141 return Types.FLOAT; 142 } 143 144 @Override 145 public Expression getExpr() { 146 return expr; 147 } 148} 149 150 151 152