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,Cast {
024        
025        private Expression expr;
026        
027        private CastDouble(Expression expr) {
028            super(expr.getStart(),expr.getEnd());
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 LitDouble.toExprDouble(dbl.doubleValue(),expr.getStart(),expr.getEnd());
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            @Override
109            public Expression getExpr() {
110                    return expr;
111            }
112    
113    }
114    
115    
116    
117