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