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.ExprString; 028import lucee.transformer.bytecode.expression.Expression; 029import lucee.transformer.bytecode.expression.ExpressionBase; 030import lucee.transformer.bytecode.literal.LitDouble; 031import lucee.transformer.bytecode.util.Methods; 032import lucee.transformer.bytecode.util.Types; 033 034import org.objectweb.asm.Type; 035import org.objectweb.asm.commons.GeneratorAdapter; 036import org.objectweb.asm.commons.Method; 037 038/** 039 * cast a Expression to a Double 040 */ 041public final class CastDouble extends ExpressionBase implements ExprDouble,Cast { 042 043 private Expression expr; 044 045 private CastDouble(Expression expr) { 046 super(expr.getStart(),expr.getEnd()); 047 this.expr=expr; 048 } 049 050 /** 051 * Create a String expression from a Expression 052 * @param expr 053 * @return String expression 054 * @throws TemplateException 055 */ 056 public static ExprDouble toExprDouble(Expression expr) { 057 if(expr instanceof ExprDouble) return (ExprDouble) expr; 058 if(expr instanceof Literal) { 059 Double dbl = ((Literal)expr).getDouble(null); 060 if(dbl!=null) return LitDouble.toExprDouble(dbl.doubleValue(),expr.getStart(),expr.getEnd()); 061 } 062 return new CastDouble(expr); 063 } 064 065 /** 066 * @see lucee.transformer.bytecode.expression.Expression#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 067 */ 068 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 069 070 GeneratorAdapter adapter = bc.getAdapter(); 071 if(expr instanceof ExprBoolean) { 072 expr.writeOut(bc,MODE_VALUE); 073 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_BOOLEAN); 074 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_BOOLEAN); 075 } 076 else if(expr instanceof ExprDouble) { 077 expr.writeOut(bc,mode); 078 //if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_DOUBLE); 079 //if(mode==MODE_REF) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE); 080 } 081 else if(expr instanceof ExprString) { 082 expr.writeOut(bc,MODE_REF); 083 if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_STRING); 084 else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_STRING); 085 } 086 else { 087 Type rtn = expr.writeOut(bc,mode); 088 if(mode==MODE_VALUE) { 089 if(!Types.isPrimitiveType(rtn)) { 090 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE); 091 } 092 else if(Types.DOUBLE_VALUE.equals(rtn)) {} 093 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 094 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_BOOLEAN); 095 } 096 else { 097 adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn})); 098 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE); 099 } 100 return Types.DOUBLE_VALUE; 101 } 102 else if(Types.isPrimitiveType(rtn)) { 103 if(Types.DOUBLE_VALUE.equals(rtn)) { 104 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE); 105 } 106 else if(Types.BOOLEAN_VALUE.equals(rtn)) { 107 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_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_DOUBLE); 112 } 113 return Types.DOUBLE; 114 } 115 //else { 116 if(!Types.DOUBLE.equals(rtn)) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE); 117 return Types.DOUBLE; 118 //} 119 } 120 121 122 if(mode==MODE_VALUE)return Types.DOUBLE_VALUE; 123 return Types.DOUBLE; 124 } 125 126 @Override 127 public Expression getExpr() { 128 return expr; 129 } 130 131} 132 133 134 135