KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > cglib > core > RemappingCodeVisitor


1 package org.logicalcobwebs.cglib.core;
2
3 import org.logicalcobwebs.asm.*;
4 import java.util.*;
5
6 public class RemappingCodeVisitor extends CodeAdapter {
7     private State state;
8     private IntRef check = new IntRef();
9
10     private static class State {
11         Map locals = new HashMap();
12         int firstLocal;
13         int nextLocal;
14
15         State(int access, Type[] args) {
16             nextLocal = ((Constants.ACC_STATIC & access) != 0) ? 0 : 1;
17             for (int i = 0; i < args.length; i++) {
18                 nextLocal += args[i].getSize();
19             }
20             firstLocal = nextLocal;
21         }
22     }
23
24     private static class IntRef {
25         int key;
26         public boolean equals(Object JavaDoc o) {
27             return key == ((IntRef)o).key;
28         }
29         public int hashCode() {
30             return key;
31         }
32     }
33     
34     public RemappingCodeVisitor(CodeVisitor v, int access, Type[] args) {
35         super(v);
36         state = new State(access, args);
37     }
38
39     public RemappingCodeVisitor(RemappingCodeVisitor wrap) {
40         super(wrap.cv);
41         this.state = wrap.state;
42     }
43
44     protected int nextLocal(int size) {
45         int var = state.nextLocal;
46         state.nextLocal += size;
47         return var;
48     }
49     
50     private int remap(int var, int size) {
51         if (var < state.firstLocal) {
52             return var;
53         }
54         check.key = (size == 2) ? ~var : var;
55         Integer JavaDoc value = (Integer JavaDoc)state.locals.get(check);
56         if (value == null) {
57             IntRef ref = new IntRef();
58             ref.key = check.key;
59             state.locals.put(ref, value = new Integer JavaDoc(nextLocal(size)));
60         }
61         return value.intValue();
62     }
63         
64     public void visitIincInsn(int var, int increment) {
65         cv.visitIincInsn(remap(var, 1), increment);
66     }
67
68     public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, Label start, Label end, int index) {
69         cv.visitLocalVariable(name, desc, start, end, remap(index, 0));
70     }
71
72     public void visitVarInsn(int opcode, int var) {
73         int size;
74         switch (opcode) {
75         case Constants.LLOAD:
76         case Constants.LSTORE:
77         case Constants.DLOAD:
78         case Constants.DSTORE:
79             size = 2;
80             break;
81         default:
82             size = 1;
83         }
84         cv.visitVarInsn(opcode, remap(var, size));
85     }
86
87     public void visitMaxs(int maxStack, int maxLocals) {
88         cv.visitMaxs(0, 0);
89     }
90 }
91
92
Popular Tags