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