001 package railo.transformer.bytecode.visitor; 002 003 import org.objectweb.asm.Label; 004 import org.objectweb.asm.Opcodes; 005 import org.objectweb.asm.commons.GeneratorAdapter; 006 007 import railo.transformer.bytecode.BytecodeContext; 008 import railo.transformer.bytecode.Position; 009 import railo.transformer.bytecode.util.ExpressionUtil; 010 import railo.transformer.bytecode.util.Types; 011 012 public final class ForVisitor implements Opcodes,LoopVisitor { 013 014 private Label l0= new Label(); 015 private Label l1= new Label(); 016 private Label l2= new Label(); 017 private Label l3= new Label(); 018 private int i; 019 private Label lend= new Label(); 020 private Label lbegin= new Label(); 021 022 public int visitBegin(GeneratorAdapter adapter, int start, boolean isLocal) { 023 adapter.visitLabel(l0); 024 025 forInit(adapter, start, isLocal); 026 027 028 adapter.visitLabel(l1); 029 adapter.visitJumpInsn(GOTO, l2); 030 adapter.visitLabel(l3); 031 032 return i; 033 } 034 public void visitEnd(BytecodeContext bc, int end, boolean isLocal,Position startline) { 035 GeneratorAdapter adapter=bc.getAdapter(); 036 037 adapter.visitLabel(lbegin); 038 forUpdate(adapter); 039 040 ExpressionUtil.visitLine(bc, startline); 041 adapter.visitLabel(l2); 042 adapter.visitVarInsn(ILOAD, i); 043 044 if(isLocal)adapter.loadLocal(end); 045 else adapter.push(end); 046 adapter.visitJumpInsn(IF_ICMPLE, l3); 047 048 adapter.visitLabel(lend); 049 050 //adapter.visitLocalVariable("i", "I", null, l1, lend, i); 051 052 } 053 054 055 private void forUpdate(GeneratorAdapter adapter) { 056 adapter.visitIincInsn(i, 1); 057 } 058 private void forInit(GeneratorAdapter adapter, int start, boolean isLocal) { 059 i=adapter.newLocal(Types.INT_VALUE); 060 if(isLocal)adapter.loadLocal(start); 061 else adapter.push(start); 062 adapter.visitVarInsn(ISTORE, i); 063 } 064 065 /** 066 * 067 * @see railo.transformer.bytecode.visitor.LoopVisitor#visitContinue(org.objectweb.asm.commons.GeneratorAdapter) 068 */ 069 public void visitContinue(BytecodeContext bc) { 070 bc.getAdapter().visitJumpInsn(Opcodes.GOTO, lbegin); 071 } 072 073 /** 074 * 075 * @see railo.transformer.bytecode.visitor.LoopVisitor#visitBreak(org.objectweb.asm.commons.GeneratorAdapter) 076 */ 077 public void visitBreak(BytecodeContext bc) { 078 bc.getAdapter().visitJumpInsn(Opcodes.GOTO, lend); 079 } 080 081 /** 082 * 083 * @see railo.transformer.bytecode.visitor.LoopVisitor#getContinueLabel() 084 */ 085 public Label getContinueLabel() { 086 return lbegin; 087 } 088 089 /** 090 * 091 * @see railo.transformer.bytecode.visitor.LoopVisitor#getBreakLabel() 092 */ 093 public Label getBreakLabel() { 094 return lend; 095 } 096 }