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