1 30 package org.objectweb.asm.util.attrs; 31 32 import java.util.List ; 33 import java.util.Map ; 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.StackMapAttribute; 39 import org.objectweb.asm.attrs.StackMapFrame; 40 import org.objectweb.asm.attrs.StackMapType; 41 42 47 public class ASMStackMapAttribute extends StackMapAttribute implements 48 ASMifiable, 49 Traceable 50 { 51 54 private int len; 55 56 public ASMStackMapAttribute() { 57 super(); 58 } 59 60 public ASMStackMapAttribute(List 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 StackMapAttribute attr = (StackMapAttribute) super.read(cr, 74 off, 75 len, 76 buf, 77 codeOff, 78 labels); 79 80 return new ASMStackMapAttribute(attr.getFrames(), len); 81 } 82 83 public void asmify(StringBuffer buf, String varName, Map labelNames) { 84 List frames = getFrames(); 85 buf.append("{\n"); 86 buf.append("StackMapAttribute ").append(varName).append("Attr"); 87 buf.append(" = new StackMapAttribute();\n"); 88 if (frames.size() > 0) { 89 for (int i = 0; i < frames.size(); i++) { 90 asmify((StackMapFrame) frames.get(i), buf, varName + "frame" 91 + i, labelNames); 92 } 93 } 94 buf.append(varName).append(".visitAttribute(").append(varName); 95 buf.append("Attr);\n}\n"); 96 } 97 98 void asmify( 99 StackMapFrame f, 100 StringBuffer buf, 101 String varName, 102 Map labelNames) 103 { 104 declareLabel(buf, labelNames, f.label); 105 buf.append("{\n"); 106 107 buf.append("StackMapFrame ") 108 .append(varName) 109 .append(" = new StackMapFrame();\n"); 110 111 buf.append(varName) 112 .append(".label = ") 113 .append(labelNames.get(f.label)) 114 .append(";\n"); 115 116 asmifyTypeInfo(buf, varName, labelNames, f.locals, "locals"); 117 asmifyTypeInfo(buf, varName, labelNames, f.stack, "stack"); 118 119 buf.append("cvAttr.frames.add(").append(varName).append(");\n"); 120 buf.append("}\n"); 121 } 122 123 void asmifyTypeInfo( 124 StringBuffer buf, 125 String varName, 126 Map labelNames, 127 List infos, 128 String field) 129 { 130 if (infos.size() > 0) { 131 buf.append("{\n"); 132 for (int i = 0; i < infos.size(); i++) { 133 StackMapType typeInfo = (StackMapType) infos.get(i); 134 String localName = varName + "Info" + i; 135 int type = typeInfo.getType(); 136 buf.append("StackMapType ") 137 .append(localName) 138 .append(" = StackMapType.getTypeInfo( StackMapType.ITEM_") 139 .append(StackMapType.ITEM_NAMES[type]) 140 .append(");\n"); 141 142 switch (type) { 143 case StackMapType.ITEM_Object: buf.append(localName) 145 .append(".setObject(\"") 146 .append(typeInfo.getObject()) 147 .append("\");\n"); 148 break; 149 150 case StackMapType.ITEM_Uninitialized: declareLabel(buf, labelNames, typeInfo.getLabel()); 152 buf.append(localName) 153 .append(".setLabel(") 154 .append(labelNames.get(typeInfo.getLabel())) 155 .append(");\n"); 156 break; 157 } 158 buf.append(varName) 159 .append(".") 160 .append(field) 161 .append(".add(") 162 .append(localName) 163 .append(");\n"); 164 } 165 buf.append("}\n"); 166 } 167 } 168 169 static void declareLabel(StringBuffer buf, Map labelNames, Label l) { 170 String name = (String ) labelNames.get(l); 171 if (name == null) { 172 name = "l" + labelNames.size(); 173 labelNames.put(l, name); 174 buf.append("Label ").append(name).append(" = new Label();\n"); 175 } 176 } 177 178 public void trace(StringBuffer buf, Map labelNames) { 179 List frames = getFrames(); 180 buf.append("StackMapTable[\n"); 181 for (int i = 0; i < frames.size(); i++) { 182 StackMapFrame f = (StackMapFrame) frames.get(i); 183 184 buf.append(" Frame:"); 185 appendLabel(buf, labelNames, f.label); 186 187 buf.append(" locals["); 188 traceTypeInfo(buf, labelNames, f.locals); 189 buf.append("]"); 190 buf.append(" stack["); 191 traceTypeInfo(buf, labelNames, f.stack); 192 buf.append("]\n"); 193 } 194 buf.append(" ] length:").append(len).append("\n"); 195 } 196 197 private void traceTypeInfo(StringBuffer buf, Map labelNames, List infos) { 198 String sep = ""; 199 for (int i = 0; i < infos.size(); i++) { 200 StackMapType t = (StackMapType) infos.get(i); 201 202 buf.append(sep).append(StackMapType.ITEM_NAMES[t.getType()]); 203 sep = ", "; 204 if (t.getType() == StackMapType.ITEM_Object) { 205 buf.append(":").append(t.getObject()); 206 } 207 if (t.getType() == StackMapType.ITEM_Uninitialized) { 208 buf.append(":"); 209 appendLabel(buf, labelNames, t.getLabel()); 210 } 211 } 212 } 213 214 protected void appendLabel(StringBuffer buf, Map labelNames, Label l) { 215 String name = (String ) labelNames.get(l); 216 if (name == null) { 217 name = "L" + labelNames.size(); 218 labelNames.put(l, name); 219 } 220 buf.append(name); 221 } 222 223 } 224 | Popular Tags |