001: /**
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */package com.uwyn.rife.asm.util.attrs;
030:
031: import java.util.List;
032: import java.util.Map;
033:
034: import com.uwyn.rife.asm.Attribute;
035: import com.uwyn.rife.asm.ClassReader;
036: import com.uwyn.rife.asm.Label;
037: import com.uwyn.rife.asm.attrs.StackMapAttribute;
038: import com.uwyn.rife.asm.attrs.StackMapFrame;
039: import com.uwyn.rife.asm.attrs.StackMapType;
040:
041: /**
042: * An {@link ASMifiable} {@link StackMapAttribute} sub class.
043: *
044: * @author Eugene Kuleshov
045: */
046: public class ASMStackMapAttribute extends StackMapAttribute implements
047: ASMifiable, Traceable {
048: /**
049: * Length of the attribute used for comparison
050: */
051: private int len;
052:
053: public ASMStackMapAttribute() {
054: super ();
055: }
056:
057: public ASMStackMapAttribute(List frames, int len) {
058: super (frames);
059: this .len = len;
060: }
061:
062: protected Attribute read(ClassReader cr, int off, int len,
063: char[] buf, int codeOff, Label[] labels) {
064: StackMapAttribute attr = (StackMapAttribute) super .read(cr,
065: off, len, buf, codeOff, labels);
066:
067: return new ASMStackMapAttribute(attr.getFrames(), len);
068: }
069:
070: public void asmify(StringBuffer buf, String varName, Map labelNames) {
071: List frames = getFrames();
072: buf.append("{\n");
073: buf.append("StackMapAttribute ").append(varName).append("Attr");
074: buf.append(" = new StackMapAttribute();\n");
075: if (frames.size() > 0) {
076: for (int i = 0; i < frames.size(); i++) {
077: asmify((StackMapFrame) frames.get(i), buf, varName
078: + "frame" + i, labelNames);
079: }
080: }
081: buf.append(varName).append(".visitAttribute(").append(varName);
082: buf.append("Attr);\n}\n");
083: }
084:
085: void asmify(StackMapFrame f, StringBuffer buf, String varName,
086: Map labelNames) {
087: declareLabel(buf, labelNames, f.label);
088: buf.append("{\n");
089:
090: buf.append("StackMapFrame ").append(varName).append(
091: " = new StackMapFrame();\n");
092:
093: buf.append(varName).append(".label = ").append(
094: labelNames.get(f.label)).append(";\n");
095:
096: asmifyTypeInfo(buf, varName, labelNames, f.locals, "locals");
097: asmifyTypeInfo(buf, varName, labelNames, f.stack, "stack");
098:
099: buf.append("cvAttr.frames.add(").append(varName).append(");\n");
100: buf.append("}\n");
101: }
102:
103: void asmifyTypeInfo(StringBuffer buf, String varName,
104: Map labelNames, List infos, String field) {
105: if (infos.size() > 0) {
106: buf.append("{\n");
107: for (int i = 0; i < infos.size(); i++) {
108: StackMapType typeInfo = (StackMapType) infos.get(i);
109: String localName = varName + "Info" + i;
110: int type = typeInfo.getType();
111: buf
112: .append("StackMapType ")
113: .append(localName)
114: .append(
115: " = StackMapType.getTypeInfo( StackMapType.ITEM_")
116: .append(StackMapType.ITEM_NAMES[type]).append(
117: ");\n");
118:
119: switch (type) {
120: case StackMapType.ITEM_Object: //
121: buf.append(localName).append(".setObject(\"")
122: .append(typeInfo.getObject()).append(
123: "\");\n");
124: break;
125:
126: case StackMapType.ITEM_Uninitialized: //
127: declareLabel(buf, labelNames, typeInfo.getLabel());
128: buf.append(localName).append(".setLabel(").append(
129: labelNames.get(typeInfo.getLabel()))
130: .append(");\n");
131: break;
132: }
133: buf.append(varName).append(".").append(field).append(
134: ".add(").append(localName).append(");\n");
135: }
136: buf.append("}\n");
137: }
138: }
139:
140: static void declareLabel(StringBuffer buf, Map labelNames, Label l) {
141: String name = (String) labelNames.get(l);
142: if (name == null) {
143: name = "l" + labelNames.size();
144: labelNames.put(l, name);
145: buf.append("Label ").append(name).append(
146: " = new Label();\n");
147: }
148: }
149:
150: public void trace(StringBuffer buf, Map labelNames) {
151: List frames = getFrames();
152: buf.append("[\n");
153: for (int i = 0; i < frames.size(); i++) {
154: StackMapFrame f = (StackMapFrame) frames.get(i);
155:
156: buf.append(" Frame:");
157: appendLabel(buf, labelNames, f.label);
158:
159: buf.append(" locals[");
160: traceTypeInfo(buf, labelNames, f.locals);
161: buf.append("]");
162: buf.append(" stack[");
163: traceTypeInfo(buf, labelNames, f.stack);
164: buf.append("]\n");
165: }
166: buf.append(" ] length:").append(len).append("\n");
167: }
168:
169: private void traceTypeInfo(StringBuffer buf, Map labelNames,
170: List infos) {
171: String sep = "";
172: for (int i = 0; i < infos.size(); i++) {
173: StackMapType t = (StackMapType) infos.get(i);
174:
175: buf.append(sep)
176: .append(StackMapType.ITEM_NAMES[t.getType()]);
177: sep = ", ";
178: if (t.getType() == StackMapType.ITEM_Object) {
179: buf.append(":").append(t.getObject());
180: }
181: if (t.getType() == StackMapType.ITEM_Uninitialized) {
182: buf.append(":");
183: appendLabel(buf, labelNames, t.getLabel());
184: }
185: }
186: }
187:
188: protected void appendLabel(StringBuffer buf, Map labelNames, Label l) {
189: String name = (String) labelNames.get(l);
190: if (name == null) {
191: name = "L" + labelNames.size();
192: labelNames.put(l, name);
193: }
194: buf.append(name);
195: }
196:
197: }
|