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