KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > commons > LocalVariablesSorter


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.tc.asm.commons;
31
32 import com.tc.asm.Label;
33 import com.tc.asm.MethodAdapter;
34 import com.tc.asm.MethodVisitor;
35 import com.tc.asm.Opcodes;
36 import com.tc.asm.Type;
37
38 /**
39  * A {@link MethodAdapter} that renumbers local variables in their order of
40  * appearance. This adapter allows one to easily add new local variables to a
41  * method.
42  *
43  * @author Chris Nokleberg
44  * @author Eric Bruneton
45  */

46 public class LocalVariablesSorter extends MethodAdapter {
47
48     /**
49      * Mapping from old to new local variable indexes. A local variable at index
50      * i of size 1 is remapped to 'mapping[2*i]', while a local variable at
51      * index i of size 2 is remapped to 'mapping[2*i+1]'.
52      */

53     private int[] mapping = new int[40];
54
55     protected final int firstLocal;
56
57     private int nextLocal;
58
59     public LocalVariablesSorter(
60         final int access,
61         final String JavaDoc desc,
62         final MethodVisitor mv)
63     {
64         super(mv);
65         Type[] args = Type.getArgumentTypes(desc);
66         nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1;
67         for (int i = 0; i < args.length; i++) {
68             nextLocal += args[i].getSize();
69         }
70         firstLocal = nextLocal;
71     }
72
73     public void visitVarInsn(final int opcode, final int var) {
74         int size;
75         switch (opcode) {
76             case Opcodes.LLOAD:
77             case Opcodes.LSTORE:
78             case Opcodes.DLOAD:
79             case Opcodes.DSTORE:
80                 size = 2;
81                 break;
82             default:
83                 size = 1;
84         }
85         mv.visitVarInsn(opcode, remap(var, size));
86     }
87
88     public void visitIincInsn(final int var, final int increment) {
89         mv.visitIincInsn(remap(var, 1), increment);
90     }
91
92     public void visitMaxs(final int maxStack, final int maxLocals) {
93         mv.visitMaxs(maxStack, nextLocal);
94     }
95
96     public void visitLocalVariable(
97         final String JavaDoc name,
98         final String JavaDoc desc,
99         final String JavaDoc signature,
100         final Label start,
101         final Label end,
102         final int index)
103     {
104         int size = "J".equals(desc) || "D".equals(desc) ? 2 : 1;
105         mv.visitLocalVariable(name, desc, signature, start, end, remap(index, size));
106     }
107
108     // -------------
109

110     protected int newLocal(final int size) {
111         int var = nextLocal;
112         nextLocal += size;
113         return var;
114     }
115
116     private int remap(final int var, final int size) {
117         if (var < firstLocal) {
118             return var;
119         }
120         int key = 2 * var + size - 1;
121         int length = mapping.length;
122         if (key >= length) {
123             int[] newMapping = new int[Math.max(2 * length, key + 1)];
124             System.arraycopy(mapping, 0, newMapping, 0, length);
125             mapping = newMapping;
126         }
127         int value = mapping[key];
128         if (value == 0) {
129             value = nextLocal + 1;
130             mapping[key] = value;
131             nextLocal += size;
132         }
133         return value - 1;
134     }
135     
136 }
137
Popular Tags