001    package railo.transformer.bytecode.op;
002    
003    import org.objectweb.asm.Label;
004    import org.objectweb.asm.Opcodes;
005    import org.objectweb.asm.Type;
006    import org.objectweb.asm.commons.GeneratorAdapter;
007    
008    import railo.runtime.exp.TemplateException;
009    import railo.transformer.bytecode.BytecodeContext;
010    import railo.transformer.bytecode.BytecodeException;
011    import railo.transformer.bytecode.Literal;
012    import railo.transformer.bytecode.cast.CastBoolean;
013    import railo.transformer.bytecode.expression.ExprBoolean;
014    import railo.transformer.bytecode.expression.Expression;
015    import railo.transformer.bytecode.expression.ExpressionBase;
016    import railo.transformer.bytecode.literal.LitBoolean;
017    import railo.transformer.bytecode.util.Methods;
018    import railo.transformer.bytecode.util.Types;
019    
020    public final class OpNegate extends ExpressionBase implements ExprBoolean {
021    
022            private ExprBoolean expr;
023    
024            private OpNegate(Expression expr, int line)  {
025            super(line);
026            this.expr=CastBoolean.toExprBoolean(expr);
027        }
028        
029        /**
030         * Create a String expression from a Expression
031         * @param left 
032         * @param right 
033         * 
034         * @return String expression
035         * @throws TemplateException 
036         */
037        public static ExprBoolean toExprBoolean(Expression expr, int line) {
038            if(expr instanceof Literal) {
039                    Boolean b=((Literal) expr).getBoolean(null);
040                    if(b!=null) {
041                            return new LitBoolean(!b.booleanValue(),line);
042                    }
043            }
044            return new OpNegate(expr,line);
045        }
046            
047            
048            /**
049             *
050             * @see railo.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
051             */
052            public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
053                    GeneratorAdapter adapter = bc.getAdapter();
054            if(mode==MODE_REF) {
055                _writeOut(bc,MODE_VALUE);
056                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_FROM_BOOLEAN);
057                return Types.BOOLEAN;
058            }
059            
060            
061            Label l1 = new Label();
062            Label l2 = new Label();
063            
064            expr.writeOut(bc, MODE_VALUE);
065            adapter.ifZCmp(Opcodes.IFEQ,l1);
066            
067            adapter.visitInsn(Opcodes.ICONST_0);
068            adapter.visitJumpInsn(Opcodes.GOTO, l2);
069            adapter.visitLabel(l1);
070            adapter.visitInsn(Opcodes.ICONST_1);
071            adapter.visitLabel(l2);
072    
073            return Types.BOOLEAN_VALUE;
074    
075            }
076    
077            /*public int getType() {
078                    return Types._BOOLEAN;
079            }*/
080    
081    }