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.op; 020 021import lucee.runtime.exp.TemplateException; 022import lucee.transformer.bytecode.BytecodeContext; 023import lucee.transformer.bytecode.BytecodeException; 024import lucee.transformer.bytecode.expression.ExprDouble; 025import lucee.transformer.bytecode.expression.Expression; 026import lucee.transformer.bytecode.expression.ExpressionBase; 027import lucee.transformer.bytecode.util.Methods; 028import lucee.transformer.bytecode.util.Types; 029 030import org.objectweb.asm.Type; 031import org.objectweb.asm.commons.GeneratorAdapter; 032import org.objectweb.asm.commons.Method; 033 034public final class OpDouble extends ExpressionBase implements ExprDouble { 035 036 private static final Method DIV_REF=new Method("divRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 037 private static final Method INTDIV_REF=new Method("intdivRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 038 private static final Method EXP_REF=new Method("exponentRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 039 040 private static final Method PLUS_REF=new Method("plusRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 041 private static final Method MINUS_REF=new Method("minusRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 042 private static final Method MODULUS_REF=new Method("modulusRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 043 private static final Method DIVIDE_REF=new Method("divideRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 044 private static final Method MULTIPLY_REF=new Method("multiplyRef",Types.DOUBLE,new Type[]{Types.OBJECT,Types.OBJECT}); 045 046 public static final int PLUS=GeneratorAdapter.ADD; 047 public static final int MINUS=GeneratorAdapter.SUB; 048 public static final int MODULUS=GeneratorAdapter.REM; 049 public static final int DIVIDE=GeneratorAdapter.DIV; 050 public static final int MULTIPLY=GeneratorAdapter.MUL; 051 public static final int EXP = 2000; 052 public static final int INTDIV = 2001; 053 054 private int operation; 055 private Expression left; 056 private Expression right; 057 058 OpDouble(Expression left, Expression right, int operation) { 059 super(left.getStart(),right.getEnd()); 060 this.left= left; 061 this.right= right; 062 this.operation=operation; 063 } 064 065 066 public Expression getLeft() { 067 return left; 068 } 069 070 public Expression getRight() { 071 return right; 072 } 073 074 public int getOperation() { 075 return operation; 076 } 077 078 /** 079 * Create a String expression from a Expression 080 * @param left 081 * @param right 082 * @param operation 083 * 084 * @return String expression 085 * @throws TemplateException 086 */ 087 public static ExprDouble toExprDouble(Expression left, Expression right,int operation) { 088 return new OpDouble(left,right,operation); 089 } 090 091 /** 092 * 093 * @see lucee.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 094 */ 095 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 096 return writeOutDouble(bc, mode) ; 097 } 098 099 public Type writeOutDouble(BytecodeContext bc, int mode) throws BytecodeException { 100 GeneratorAdapter adapter = bc.getAdapter(); 101 102 left.writeOut(bc,MODE_REF); 103 right.writeOut(bc,MODE_REF); 104 105 106 if(operation==EXP) { 107 adapter.invokeStatic(Types.OPERATOR,EXP_REF); 108 } 109 else if(operation==DIVIDE) { 110 adapter.invokeStatic(Types.OPERATOR,DIV_REF); 111 } 112 else if(operation==INTDIV) { 113 adapter.invokeStatic(Types.OPERATOR,INTDIV_REF); 114 } 115 else if(operation==PLUS) { 116 adapter.invokeStatic(Types.OPERATOR,PLUS_REF); 117 } 118 else if(operation==MINUS) { 119 adapter.invokeStatic(Types.OPERATOR,MINUS_REF); 120 } 121 else if(operation==MODULUS) { 122 adapter.invokeStatic(Types.OPERATOR,MODULUS_REF); 123 } 124 else if(operation==DIVIDE) { 125 adapter.invokeStatic(Types.OPERATOR,DIVIDE_REF); 126 } 127 else if(operation==MULTIPLY) { 128 adapter.invokeStatic(Types.OPERATOR,MULTIPLY_REF); 129 } 130 131 132 if(mode==MODE_VALUE) { 133 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_DOUBLE); 134 return Types.DOUBLE_VALUE; 135 } 136 137 138 139 return Types.DOUBLE; 140 } 141 142}