KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > asm > util > attrs > ASMStackMapTableAttribute


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 org.objectweb.asm.util.attrs;
31
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import org.objectweb.asm.Attribute;
36 import org.objectweb.asm.ClassReader;
37 import org.objectweb.asm.Label;
38 import org.objectweb.asm.attrs.StackMapTableAttribute;
39 import org.objectweb.asm.attrs.StackMapFrame;
40 import org.objectweb.asm.attrs.StackMapType;
41
42 /**
43  * An {@link ASMifiable} {@link StackMapTableAttribute} sub class.
44  *
45  * @author Eugene Kuleshov
46  */

47 public class ASMStackMapTableAttribute extends StackMapTableAttribute implements
48         ASMifiable,
49         Traceable
50 {
51     /**
52      * Length of the attribute used for comparison
53      */

54     private int len;
55
56     public ASMStackMapTableAttribute() {
57         super();
58     }
59
60     public ASMStackMapTableAttribute(List JavaDoc frames, int len) {
61         super(frames);
62         this.len = len;
63     }
64
65     protected Attribute read(
66         ClassReader cr,
67         int off,
68         int len,
69         char[] buf,
70         int codeOff,
71         Label[] labels)
72     {
73         StackMapTableAttribute attr = (StackMapTableAttribute) super.read(cr,
74                 off,
75                 len,
76                 buf,
77                 codeOff,
78                 labels);
79
80         return new ASMStackMapTableAttribute(attr.getFrames(), len);
81     }
82
83     public void asmify(StringBuffer JavaDoc buf, String JavaDoc varName, Map JavaDoc labelNames) {
84         List JavaDoc frames = getFrames();
85         if (frames.size() == 0) {
86             buf.append("List frames = Collections.EMPTY_LIST;\n");
87         } else {
88             buf.append("List frames = new ArrayList();\n");
89             for (int i = 0; i < frames.size(); i++) {
90                 buf.append("{\n");
91                 StackMapFrame f = (StackMapFrame) frames.get(i);
92                 declareLabel(buf, labelNames, f.label);
93
94                 String JavaDoc frameVar = varName + "frame" + i;
95                 asmifyTypeInfo(buf, frameVar, labelNames, f.locals, "locals");
96                 asmifyTypeInfo(buf, frameVar, labelNames, f.stack, "stack");
97
98                 buf.append("StackMapFrame ")
99                         .append(frameVar)
100                         .append(" = new StackMapFrame(")
101                         .append(labelNames.get(f.label))
102                         .append(", locals, stack);\n");
103                 buf.append("frames.add(").append(frameVar).append(");\n");
104                 buf.append("}\n");
105             }
106         }
107         buf.append("StackMapTableAttribute ").append(varName);
108         buf.append(" = new StackMapTableAttribute(frames);\n");
109     }
110
111     void asmifyTypeInfo(
112         StringBuffer JavaDoc buf,
113         String JavaDoc varName,
114         Map JavaDoc labelNames,
115         List JavaDoc infos,
116         String JavaDoc field)
117     {
118         if (infos.size() == 0) {
119             buf.append("List ")
120                     .append(field)
121                     .append(" = Collections.EMPTY_LIST;\n");
122         } else {
123             buf.append("List ").append(field).append(" = new ArrayList();\n");
124             buf.append("{\n");
125             for (int i = 0; i < infos.size(); i++) {
126                 StackMapType typeInfo = (StackMapType) infos.get(i);
127                 String JavaDoc localName = varName + "Info" + i;
128                 int type = typeInfo.getType();
129                 buf.append("StackMapType ")
130                         .append(localName)
131                         .append(" = StackMapType.getTypeInfo( StackMapType.ITEM_")
132                         .append(StackMapType.ITEM_NAMES[type])
133                         .append(");\n");
134
135                 switch (type) {
136                     case StackMapType.ITEM_Object: //
137
buf.append(localName)
138                                 .append(".setObject(\"")
139                                 .append(typeInfo.getObject())
140                                 .append("\");\n");
141                         break;
142
143                     case StackMapType.ITEM_Uninitialized: //
144
declareLabel(buf, labelNames, typeInfo.getLabel());
145                         buf.append(localName)
146                                 .append(".setLabel(")
147                                 .append(labelNames.get(typeInfo.getLabel()))
148                                 .append(");\n");
149                         break;
150                 }
151                 buf.append(field)
152                         .append(".add(")
153                         .append(localName)
154                         .append(");\n");
155             }
156             buf.append("}\n");
157         }
158     }
159
160     static void declareLabel(StringBuffer JavaDoc buf, Map JavaDoc labelNames, Label l) {
161         String JavaDoc name = (String JavaDoc) labelNames.get(l);
162         if (name == null) {
163             name = "l" + labelNames.size();
164             labelNames.put(l, name);
165             buf.append("Label ").append(name).append(" = new Label();\n");
166         }
167     }
168
169     public void trace(StringBuffer JavaDoc buf, Map JavaDoc labelNames) {
170         List JavaDoc frames = getFrames();
171         buf.append("StackMapTable[\n");
172         for (int i = 0; i < frames.size(); i++) {
173             StackMapFrame f = (StackMapFrame) frames.get(i);
174
175             buf.append(" Frame:");
176             appendLabel(buf, labelNames, f.label);
177
178             buf.append(" locals[");
179             traceTypeInfo(buf, labelNames, f.locals);
180             buf.append("]");
181             buf.append(" stack[");
182             traceTypeInfo(buf, labelNames, f.stack);
183             buf.append("]\n");
184         }
185         buf.append(" ] length:").append(len).append("\n");
186     }
187
188     private void traceTypeInfo(StringBuffer JavaDoc buf, Map JavaDoc labelNames, List JavaDoc infos) {
189         String JavaDoc sep = "";
190         for (int i = 0; i < infos.size(); i++) {
191             StackMapType t = (StackMapType) infos.get(i);
192
193             buf.append(sep).append(StackMapType.ITEM_NAMES[t.getType()]);
194             sep = ", ";
195             if (t.getType() == StackMapType.ITEM_Object) {
196                 buf.append(":").append(t.getObject());
197             }
198             if (t.getType() == StackMapType.ITEM_Uninitialized) {
199                 buf.append(":");
200                 appendLabel(buf, labelNames, t.getLabel());
201             }
202         }
203     }
204
205     protected void appendLabel(StringBuffer JavaDoc buf, Map JavaDoc labelNames, Label l) {
206         String JavaDoc name = (String JavaDoc) labelNames.get(l);
207         if (name == null) {
208             name = "L" + labelNames.size();
209             labelNames.put(l, name);
210         }
211         buf.append(name);
212     }
213
214 }
215
Popular Tags