KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > core > RemappingCodeVisitor


1 /*
2  * Copyright 2003 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.sf.cglib.core;
17
18 import org.objectweb.asm.*;
19 import java.util.*;
20
21 public class RemappingCodeVisitor extends CodeAdapter {
22     private State state;
23     private IntRef check = new IntRef();
24
25     private static class State {
26         Map locals = new HashMap();
27         int firstLocal;
28         int nextLocal;
29
30         State(int access, Type[] args) {
31             nextLocal = ((Constants.ACC_STATIC & access) != 0) ? 0 : 1;
32             for (int i = 0; i < args.length; i++) {
33                 nextLocal += args[i].getSize();
34             }
35             firstLocal = nextLocal;
36         }
37     }
38
39     private static class IntRef {
40         int key;
41         public boolean equals(Object JavaDoc o) {
42             return key == ((IntRef)o).key;
43         }
44         public int hashCode() {
45             return key;
46         }
47     }
48     
49     public RemappingCodeVisitor(CodeVisitor v, int access, Type[] args) {
50         super(v);
51         state = new State(access, args);
52     }
53
54     public RemappingCodeVisitor(RemappingCodeVisitor wrap) {
55         super(wrap.cv);
56         this.state = wrap.state;
57     }
58
59     protected int nextLocal(int size) {
60         int var = state.nextLocal;
61         state.nextLocal += size;
62         return var;
63     }
64     
65     private int remap(int var, int size) {
66         if (var < state.firstLocal) {
67             return var;
68         }
69         Integer JavaDoc value = remapHelper(var, (size == 0) ? 1 : size);
70         if (value == null) {
71             if (size == 0) {
72                 value = remapHelper(var, 2);
73                 if (value == null) {
74                     throw new IllegalStateException JavaDoc("Unknown local variable " + var);
75                 }
76             } else {
77                 IntRef ref = new IntRef();
78                 ref.key = getKey(var, size);
79                 state.locals.put(ref, value = new Integer JavaDoc(nextLocal(size)));
80             }
81         }
82         // System.err.println("remap(" + var + ", " + size + ") -> " + value.intValue());
83
return value.intValue();
84     }
85
86     private Integer JavaDoc remapHelper(int var, int size) {
87         check.key = getKey(var, size);
88         return (Integer JavaDoc)state.locals.get(check);
89     }
90
91     private int getKey(int var, int size) {
92         return (size == 2) ? ~var : var;
93     }
94
95     public void visitIincInsn(int var, int increment) {
96         cv.visitIincInsn(remap(var, 1), increment);
97     }
98
99     public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, Label start, Label end, int index) {
100         cv.visitLocalVariable(name, desc, start, end, remap(index, 0));
101     }
102
103     public void visitVarInsn(int opcode, int var) {
104         int size;
105         switch (opcode) {
106         case Constants.LLOAD:
107         case Constants.LSTORE:
108         case Constants.DLOAD:
109         case Constants.DSTORE:
110             size = 2;
111             break;
112         default:
113             size = 1;
114         }
115         cv.visitVarInsn(opcode, remap(var, size));
116     }
117
118     public void visitMaxs(int maxStack, int maxLocals) {
119         cv.visitMaxs(0, 0);
120     }
121 }
122
123
Popular Tags