1 package com.sun.org.apache.bcel.internal.util; 2 3 56 import com.sun.org.apache.bcel.internal.classfile.*; 57 import com.sun.org.apache.bcel.internal.generic.*; 58 import com.sun.org.apache.bcel.internal.Repository; 59 import com.sun.org.apache.bcel.internal.Constants; 60 import java.io.*; 61 62 72 public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor { 73 private JavaClass _clazz; 74 private PrintWriter _out; 75 private ConstantPoolGen _cp; 76 77 80 public BCELifier(JavaClass clazz, OutputStream out) { 81 _clazz = clazz; 82 _out = new PrintWriter(out); 83 _cp = new ConstantPoolGen(_clazz.getConstantPool()); 84 } 85 86 88 public void start() { 89 visitJavaClass(_clazz); 90 _out.flush(); 91 } 92 93 public void visitJavaClass(JavaClass clazz) { 94 String class_name = clazz.getClassName(); 95 String super_name = clazz.getSuperclassName(); 96 String package_name = clazz.getPackageName(); 97 String inter = Utility.printArray(clazz.getInterfaceNames(), 98 false, true); 99 if(!"".equals(package_name)) { 100 class_name = class_name.substring(package_name.length() + 1); 101 _out.println("package " + package_name + ";\n"); 102 } 103 104 _out.println("import com.sun.org.apache.bcel.internal.generic.*;"); 105 _out.println("import com.sun.org.apache.bcel.internal.classfile.*;"); 106 _out.println("import com.sun.org.apache.bcel.internal.*;"); 107 _out.println("import java.io.*;\n"); 108 109 _out.println("public class " + class_name + "Creator implements Constants {"); 110 _out.println(" private InstructionFactory _factory;"); 111 _out.println(" private ConstantPoolGen _cp;"); 112 _out.println(" private ClassGen _cg;\n"); 113 114 _out.println(" public " + class_name + "Creator() {"); 115 _out.println(" _cg = new ClassGen(\"" + 116 (("".equals(package_name))? class_name : 117 package_name + "." + class_name) + 118 "\", \"" + super_name + "\", " + 119 "\"" + clazz.getSourceFileName() + "\", " + 120 printFlags(clazz.getAccessFlags(), true) + ", " + 121 "new String[] { " + inter + " });\n"); 122 123 _out.println(" _cp = _cg.getConstantPool();"); 124 _out.println(" _factory = new InstructionFactory(_cg, _cp);"); 125 _out.println(" }\n"); 126 127 printCreate(); 128 129 Field[] fields = clazz.getFields(); 130 131 if(fields.length > 0) { 132 _out.println(" private void createFields() {"); 133 _out.println(" FieldGen field;"); 134 135 for(int i=0; i < fields.length; i++) { 136 fields[i].accept(this); 137 } 138 139 _out.println(" }\n"); 140 } 141 142 Method[] methods = clazz.getMethods(); 143 144 for(int i=0; i < methods.length; i++) { 145 _out.println(" private void createMethod_" + i + "() {"); 146 147 methods[i].accept(this); 148 _out.println(" }\n"); 149 } 150 151 printMain(); 152 _out.println("}"); 153 } 154 155 private void printCreate() { 156 _out.println(" public void create(OutputStream out) throws IOException {"); 157 158 Field[] fields = _clazz.getFields(); 159 if(fields.length > 0) { 160 _out.println(" createFields();"); 161 } 162 163 Method[] methods = _clazz.getMethods(); 164 for(int i=0; i < methods.length; i++) { 165 _out.println(" createMethod_" + i + "();"); 166 } 167 168 _out.println(" _cg.getJavaClass().dump(out);"); 169 170 _out.println(" }\n"); 171 } 172 173 private void printMain() { 174 String class_name = _clazz.getClassName(); 175 176 _out.println(" public static void _main(String[] args) throws Exception {"); 177 _out.println(" " + class_name + "Creator creator = new " + 178 class_name + "Creator();"); 179 _out.println(" creator.create(new FileOutputStream(\"" + class_name + 180 ".class\"));"); 181 _out.println(" }"); 182 } 183 184 public void visitField(Field field) { 185 _out.println("\n field = new FieldGen(" + 186 printFlags(field.getAccessFlags()) + 187 ", " + printType(field.getSignature()) + ", \"" + 188 field.getName() + "\", _cp);"); 189 190 ConstantValue cv = field.getConstantValue(); 191 192 if(cv != null) { 193 String value = cv.toString(); 194 _out.println(" field.setInitValue(" + value + ")"); 195 } 196 197 _out.println(" _cg.addField(field.getField());"); 198 } 199 200 public void visitMethod(Method method) { 201 MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); 202 203 Type result_type = mg.getReturnType(); 204 Type[] arg_types = mg.getArgumentTypes(); 205 206 _out.println(" InstructionList il = new InstructionList();"); 207 _out.println(" MethodGen method = new MethodGen(" + 208 printFlags(method.getAccessFlags()) + 209 ", " + printType(result_type) + 210 ", " + printArgumentTypes(arg_types) + ", " + 211 "new String[] { " + 212 Utility.printArray(mg.getArgumentNames(), false, true) + 213 " }, \"" + method.getName() + "\", \"" + 214 _clazz.getClassName() + "\", il, _cp);\n"); 215 216 BCELFactory factory = new BCELFactory(mg, _out); 217 factory.start(); 218 219 _out.println(" method.setMaxStack();"); 220 _out.println(" method.setMaxLocals();"); 221 _out.println(" _cg.addMethod(method.getMethod());"); 222 _out.println(" il.dispose();"); 223 } 224 225 static String printFlags(int flags) { 226 return printFlags(flags, false); 227 } 228 229 static String printFlags(int flags, boolean for_class) { 230 if(flags == 0) 231 return "0"; 232 233 StringBuffer buf = new StringBuffer (); 234 for(int i=0, pow=1; i <= Constants.MAX_ACC_FLAG; i++) { 235 if((flags & pow) != 0) { 236 if((pow == Constants.ACC_SYNCHRONIZED) && for_class) 237 buf.append("ACC_SUPER | "); 238 else 239 buf.append("ACC_" + Constants.ACCESS_NAMES[i].toUpperCase() + " | "); 240 } 241 242 pow <<= 1; 243 } 244 245 String str = buf.toString(); 246 return str.substring(0, str.length() - 3); 247 } 248 249 static String printArgumentTypes(Type[] arg_types) { 250 if(arg_types.length == 0) 251 return "Type.NO_ARGS"; 252 253 StringBuffer args = new StringBuffer (); 254 255 for(int i=0; i < arg_types.length; i++) { 256 args.append(printType(arg_types[i])); 257 258 if(i < arg_types.length - 1) 259 args.append(", "); 260 } 261 262 return "new Type[] { " + args.toString() + " }"; 263 } 264 265 static String printType(Type type) { 266 return printType(type.getSignature()); 267 } 268 269 static String printType(String signature) { 270 Type type = Type.getType(signature); 271 byte t = type.getType(); 272 273 if(t <= Constants.T_VOID) { 274 return "Type." + Constants.TYPE_NAMES[t].toUpperCase(); 275 } else if(type.toString().equals("java.lang.String")) { 276 return "Type.STRING"; 277 } else if(type.toString().equals("java.lang.Object")) { 278 return "Type.OBJECT"; 279 } else if(type.toString().equals("java.lang.StringBuffer")) { 280 return "Type.STRINGBUFFER"; 281 } else if(type instanceof ArrayType) { 282 ArrayType at = (ArrayType)type; 283 284 return "new ArrayType(" + printType(at.getBasicType()) + 285 ", " + at.getDimensions() + ")"; 286 } else { 287 return "new ObjectType(\"" + Utility.signatureToString(signature, false) + 288 "\")"; 289 } 290 } 291 292 294 public static void _main(String [] argv) throws Exception { 295 JavaClass java_class; 296 String name = argv[0]; 297 298 if((java_class = Repository.lookupClass(name)) == null) 299 java_class = new ClassParser(name).parse(); 301 BCELifier bcelifier = new BCELifier(java_class, System.out); 302 bcelifier.start(); 303 } 304 } 305 | Popular Tags |