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