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 lucee.transformer.bytecode.BytecodeContext;
022import lucee.transformer.bytecode.BytecodeException;
023import lucee.transformer.bytecode.Position;
024import lucee.transformer.bytecode.statement.FlowControlFinal;
025import lucee.transformer.bytecode.statement.FlowControlFinalImpl;
026import lucee.transformer.bytecode.util.Types;
027import lucee.transformer.bytecode.visitor.NotVisitor;
028import lucee.transformer.bytecode.visitor.OnFinally;
029import lucee.transformer.bytecode.visitor.TryFinallyVisitor;
030
031import org.objectweb.asm.Label;
032import org.objectweb.asm.Opcodes;
033import org.objectweb.asm.Type;
034import org.objectweb.asm.commons.GeneratorAdapter;
035import org.objectweb.asm.commons.Method;
036
037public final class TagSilent extends TagBase {
038
039        // boolean setSilent()
040        private static final Method SET_SILENT = new Method(
041                        "setSilent",
042                        Types.BOOLEAN_VALUE,
043                        new Type[]{}
044        );
045
046        // boolean unsetSilent();
047        private static final Method UNSET_SILENT = new Method(
048                        "unsetSilent",
049                        Types.BOOLEAN_VALUE,
050                        new Type[]{}
051        );
052
053        private FlowControlFinalImpl fcf;
054        
055        public TagSilent(Position start,Position end) {
056                super(start,end);
057        }
058
059        /**
060         *
061         * @see lucee.transformer.bytecode.statement.tag.TagBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter)
062         */
063        public void _writeOut(BytecodeContext bc) throws BytecodeException {
064                final GeneratorAdapter adapter = bc.getAdapter();
065                
066                final int silentMode=adapter.newLocal(Types.BOOLEAN_VALUE);
067                
068                // boolean silentMode= pc.setSilent();
069                adapter.loadArg(0);
070                adapter.invokeVirtual(Types.PAGE_CONTEXT, SET_SILENT);
071                adapter.storeLocal(silentMode);
072                
073                // call must be 
074                TryFinallyVisitor tfv=new TryFinallyVisitor(new OnFinally() {
075                        public void _writeOut(BytecodeContext bc) {
076                                //if(fcf!=null && fcf.getAfterFinalGOTOLabel()!=null)ASMUtil.visitLabel(adapter,fcf.getFinalEntryLabel());
077                                // if(!silentMode)pc.unsetSilent();
078                                Label _if=new Label();
079                                adapter.loadLocal(silentMode);
080                                NotVisitor.visitNot(bc);
081                                adapter.ifZCmp(Opcodes.IFEQ, _if);
082                                        adapter.loadArg(0);
083                                        adapter.invokeVirtual(Types.PAGE_CONTEXT, UNSET_SILENT);
084                                        adapter.pop();
085                                
086                                adapter.visitLabel(_if);
087                                /*if(fcf!=null) {
088                                        Label l = fcf.getAfterFinalGOTOLabel();
089                                        if(l!=null)adapter.visitJumpInsn(Opcodes.GOTO, l);
090                                }*/
091                        }
092                },getFlowControlFinal());
093                tfv.visitTryBegin(bc);
094                        getBody().writeOut(bc);
095                tfv.visitTryEnd(bc);
096
097        }
098
099        @Override
100        public FlowControlFinal getFlowControlFinal() {
101                if(fcf==null)fcf = new FlowControlFinalImpl();
102                return fcf;
103        }
104
105}