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 }