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