1 package net.sf.cglib.core;
2
3 import org.objectweb.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 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 value = (Integer)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(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 name, String 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
This page was automatically generated by Maven