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.StackMapTableAttribute; 39 import org.objectweb.asm.attrs.StackMapFrame; 40 import org.objectweb.asm.attrs.StackMapType; 41 42 47 public class ASMStackMapTableAttribute extends StackMapTableAttribute implements 48 ASMifiable, 49 Traceable 50 { 51 54 private int len; 55 56 public ASMStackMapTableAttribute() { 57 super(); 58 } 59 60 public ASMStackMapTableAttribute(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 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 buf, String varName, Map labelNames) { 84 List 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 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 buf, 113 String varName, 114 Map labelNames, 115 List infos, 116 String 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 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: buf.append(localName) 138 .append(".setObject(\"") 139 .append(typeInfo.getObject()) 140 .append("\");\n"); 141 break; 142 143 case StackMapType.ITEM_Uninitialized: 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 buf, Map labelNames, Label l) { 161 String name = (String ) 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 buf, Map labelNames) { 170 List 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 buf, Map labelNames, List infos) { 189 String 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 buf, Map labelNames, Label l) { 206 String name = (String ) 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 |