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.statement.tag; 020 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024 025import lucee.transformer.bytecode.BodyBase; 026import lucee.transformer.bytecode.BytecodeContext; 027import lucee.transformer.bytecode.BytecodeException; 028import lucee.transformer.bytecode.Position; 029import lucee.transformer.bytecode.Statement; 030import lucee.transformer.bytecode.cast.CastBoolean; 031import lucee.transformer.bytecode.expression.ExprBoolean; 032import lucee.transformer.bytecode.expression.Expression; 033import lucee.transformer.bytecode.util.ExpressionUtil; 034 035import org.objectweb.asm.Label; 036import org.objectweb.asm.Opcodes; 037import org.objectweb.asm.commons.GeneratorAdapter; 038 039public final class TagIf extends TagBaseNoFinal { 040 041 042 public TagIf(Position start,Position end) { 043 super(start,end); 044 } 045 046 public void _writeOut(BytecodeContext bc) throws BytecodeException { 047 GeneratorAdapter adapter = bc.getAdapter(); 048 049 Label end = new Label(); 050 List<Statement> tmp=new ArrayList<Statement>(); 051 Iterator<Statement> it = getBody().getStatements().iterator(); 052 Tag t; 053 Label endIf=writeOutElseIfStart(bc, this); 054 boolean hasElse=false; 055 while(it.hasNext()) { 056 Statement stat = it.next(); 057 if(!hasElse && stat instanceof Tag) { 058 t=(Tag) stat; 059 060 if(t.getTagLibTag().getTagClassName().equals("lucee.runtime.tag.ElseIf")) { 061 __writeOut(bc,tmp); 062 writeOutElseIfEnd(adapter, endIf, end); 063 endIf=writeOutElseIfStart(bc,t); 064 continue; 065 } 066 else if(t.getTagLibTag().getTagClassName().equals("lucee.runtime.tag.Else")) { 067 __writeOut(bc,tmp); 068 ExpressionUtil.visitLine(bc, t.getStart()); 069 hasElse=true; 070 writeOutElseIfEnd(adapter, endIf, end); 071 continue; 072 } 073 } 074 tmp.add(stat); 075 //ExpressionUtil.writeOut(stat, bc); 076 } 077 __writeOut(bc,tmp); 078 079 if(!hasElse)writeOutElseIfEnd(adapter, endIf, end); 080 081 adapter.visitLabel(end); 082 } 083 084 private void __writeOut(BytecodeContext bc, List<Statement> statements) throws BytecodeException { 085 if(statements.size()>0) { 086 BodyBase.writeOut(bc, statements); 087 statements.clear(); 088 } 089 } 090 091 private static Label writeOutElseIfStart(BytecodeContext bc, Tag tag) throws BytecodeException { 092 GeneratorAdapter adapter = bc.getAdapter(); 093 094 ExprBoolean cont = CastBoolean.toExprBoolean(tag.getAttribute("condition").getValue()); 095 096 Label endIf = new Label(); 097 098 ExpressionUtil.visitLine(bc, tag.getStart()); 099 cont.writeOut(bc,Expression.MODE_VALUE); 100 adapter.ifZCmp(Opcodes.IFEQ, endIf); 101 return endIf; 102 } 103 private static void writeOutElseIfEnd(GeneratorAdapter adapter, Label endIf, Label end) { 104 adapter.visitJumpInsn(Opcodes.GOTO, end); 105 adapter.visitLabel(endIf); 106 } 107}