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.visitor; 020 021import lucee.transformer.bytecode.BytecodeContext; 022import lucee.transformer.bytecode.Position; 023import lucee.transformer.bytecode.util.ExpressionUtil; 024import lucee.transformer.bytecode.util.Types; 025 026import org.objectweb.asm.Label; 027import org.objectweb.asm.Opcodes; 028import org.objectweb.asm.commons.GeneratorAdapter; 029 030public final class ForVisitor implements Opcodes,LoopVisitor { 031 032 private Label l0= new Label(); 033 private Label l1= new Label(); 034 private Label l2= new Label(); 035 private Label l3= new Label(); 036 private int i; 037 private Label lend= new Label(); 038 private Label lbegin= new Label(); 039 040 public int visitBegin(GeneratorAdapter adapter, int start, boolean isLocal) { 041 adapter.visitLabel(l0); 042 043 forInit(adapter, start, isLocal); 044 045 046 adapter.visitLabel(l1); 047 adapter.visitJumpInsn(GOTO, l2); 048 adapter.visitLabel(l3); 049 050 return i; 051 } 052 public void visitEnd(BytecodeContext bc, int end, boolean isLocal,Position startline) { 053 GeneratorAdapter adapter=bc.getAdapter(); 054 055 adapter.visitLabel(lbegin); 056 forUpdate(adapter); 057 058 ExpressionUtil.visitLine(bc, startline); 059 adapter.visitLabel(l2); 060 adapter.visitVarInsn(ILOAD, i); 061 062 if(isLocal)adapter.loadLocal(end); 063 else adapter.push(end); 064 adapter.visitJumpInsn(IF_ICMPLE, l3); 065 066 adapter.visitLabel(lend); 067 068 //adapter.visitLocalVariable("i", "I", null, l1, lend, i); 069 070 } 071 072 073 private void forUpdate(GeneratorAdapter adapter) { 074 adapter.visitIincInsn(i, 1); 075 } 076 private void forInit(GeneratorAdapter adapter, int start, boolean isLocal) { 077 i=adapter.newLocal(Types.INT_VALUE); 078 if(isLocal)adapter.loadLocal(start); 079 else adapter.push(start); 080 adapter.visitVarInsn(ISTORE, i); 081 } 082 083 /** 084 * 085 * @see lucee.transformer.bytecode.visitor.LoopVisitor#visitContinue(org.objectweb.asm.commons.GeneratorAdapter) 086 */ 087 public void visitContinue(BytecodeContext bc) { 088 bc.getAdapter().visitJumpInsn(Opcodes.GOTO, lbegin); 089 } 090 091 /** 092 * 093 * @see lucee.transformer.bytecode.visitor.LoopVisitor#visitBreak(org.objectweb.asm.commons.GeneratorAdapter) 094 */ 095 public void visitBreak(BytecodeContext bc) { 096 bc.getAdapter().visitJumpInsn(Opcodes.GOTO, lend); 097 } 098 099 /** 100 * 101 * @see lucee.transformer.bytecode.visitor.LoopVisitor#getContinueLabel() 102 */ 103 public Label getContinueLabel() { 104 return lbegin; 105 } 106 107 /** 108 * 109 * @see lucee.transformer.bytecode.visitor.LoopVisitor#getBreakLabel() 110 */ 111 public Label getBreakLabel() { 112 return lend; 113 } 114}