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