1 31 package org.objectweb.proactive.core.component.asmgen; 32 33 import java.lang.reflect.InvocationTargetException ; 34 import java.lang.reflect.Method ; 35 import java.lang.reflect.Modifier ; 36 37 import java.util.Vector ; 38 39 import org.objectweb.asm.ClassWriter; 40 import org.objectweb.asm.CodeVisitor; 41 import org.objectweb.asm.Constants; 42 import org.objectweb.asm.Type; 43 44 import org.objectweb.proactive.core.ProActiveRuntimeException; 45 46 47 54 public abstract class AbstractInterfaceClassGenerator implements Constants { 55 protected static final String METHODCALL_TYPE = "Lorg/objectweb/proactive/core/mop/MethodCall;"; 57 protected static final String OBJECT_TYPE = "Ljava/lang/Object;"; 58 protected static final String OBJECT_ARRAY_TYPE = "[Ljava/lang/Object;"; 59 protected static final String METHOD_TYPE = "Ljava/lang/reflect/Method;"; 60 protected static final String METHOD_ARRAY_TYPE = "[Ljava/lang/reflect/Method;"; 61 protected static final String FUNCTIONAL_INTERFACE_NAME_TYPE = "Ljava/lang/String;"; 62 protected static final String FUNCTIONAL_INTERFACE_NAME_FIELD_NAME = "fcFunctionalInterfaceName"; 63 protected static final String SUPER_CLASS_NAME = "org/objectweb/proactive/core/component/ProActiveInterface"; 64 65 protected Class cl; 68 protected String className; 69 protected String packageName; 70 protected Method [] methods; 71 protected Vector interfacesToImplement; protected ClassWriter classGenerator; 73 74 protected String stubClassSimpleName; 77 protected String stubClassFullName; 78 79 82 protected abstract void createStaticInitializer() throws ClassNotFoundException ; 83 84 87 protected abstract void createFields(); 88 89 92 protected abstract void createDefaultMethods(); 93 94 100 protected abstract CodeVisitor createMethod(int i, Method method); 101 102 105 protected abstract void createStaticVariables(); 106 107 static void pushInt(CodeVisitor cv, int i) { 109 if ((i >= -128) && (i < 128)) { 110 cv.visitIntInsn(BIPUSH, i); 111 } else if ((i >= -32768) && (i < 32768)) { 112 cv.visitIntInsn(SIPUSH, i); 113 } else { 114 cv.visitLdcInsn(new Integer (i)); 115 } 116 } 117 118 122 protected static int convertJavaModifierToASM(int javaModifier) { 123 int result = 0; 124 125 if (Modifier.isAbstract(javaModifier)) { 126 result = result | Constants.ACC_ABSTRACT; 127 } 128 if (Modifier.isFinal(javaModifier)) { 129 result = result | Constants.ACC_FINAL; 130 } 131 if (Modifier.isInterface(javaModifier)) { 132 result = result | Constants.ACC_INTERFACE; 133 } 134 if (Modifier.isNative(javaModifier)) { 135 result = result | Constants.ACC_NATIVE; 136 } 137 if (Modifier.isPrivate(javaModifier)) { 138 result = result | Constants.ACC_PRIVATE; 139 } 140 if (Modifier.isProtected(javaModifier)) { 141 result = result | Constants.ACC_PROTECTED; 142 } 143 if (Modifier.isPublic(javaModifier)) { 144 result = result | Constants.ACC_PUBLIC; 145 } 146 if (Modifier.isStatic(javaModifier)) { 147 result = result | Constants.ACC_STATIC; 148 } 149 if (Modifier.isSynchronized(javaModifier)) { 150 result = result | Constants.ACC_SYNCHRONIZED; 151 } 152 if (Modifier.isTransient(javaModifier)) { 153 result = result | Constants.ACC_TRANSIENT; 154 } 155 if (Modifier.isVolatile(javaModifier)) { 156 result = result | Constants.ACC_VOLATILE; 157 } 158 159 return result; 160 } 161 162 166 protected static int removeNativeAndAbstractModifiers(int modifiers) { 167 int result = modifiers & (~Modifier.NATIVE); 171 result = result & (~Modifier.ABSTRACT); 172 return result; 173 } 174 175 178 public String getStubClassFullName() { 179 return this.stubClassFullName; 180 } 181 182 186 public byte[] create() throws ClassNotFoundException { 187 this.classGenerator = this.createClassGenerator(); 189 190 191 this.createConstructor(); 193 194 for (int i = 0; i < this.methods.length; i++) { 196 if (!(methods[i].getName().equals("getProxy") || methods[i].getName().equals("setProxy"))) { 198 CodeVisitor mg = this.createMethod(i, this.methods[i]); 199 } 200 } 201 202 this.createDefaultMethods(); 203 204 205 this.createFields(); 207 208 209 this.createStaticVariables(); 211 212 213 this.createStaticInitializer(); 215 216 return this.classGenerator.toByteArray(); 217 } 218 219 222 protected ClassWriter createClassGenerator() { 223 String [] interfaces = new String [interfacesToImplement.size()]; 224 for (int i = 0; i < interfacesToImplement.size(); i++) { 225 interfaces[i] = ((Class ) interfacesToImplement.get(i)).getName().replace('.', '/'); 226 } 227 228 ClassWriter cw = new ClassWriter(true); 229 cw.visit(Constants.ACC_PUBLIC | Constants.ACC_SUPER, 231 this.stubClassFullName, SUPER_CLASS_NAME, interfaces, "<generated>"); 234 return cw; 235 } 236 237 protected void createConstructor() { 238 CodeVisitor cv = this.classGenerator.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 240 241 cv.visitVarInsn(ALOAD, 0); 243 244 cv.visitMethodInsn(INVOKESPECIAL, SUPER_CLASS_NAME, "<init>", "()V"); 246 247 cv.visitInsn(RETURN); 249 250 251 cv.visitMaxs(0, 0); 254 255 return; 256 } 257 258 protected CodeVisitor createMethodGenerator(Method m) { 259 int flags = convertJavaModifierToASM(m.getModifiers()); 261 262 263 flags = removeNativeAndAbstractModifiers(flags); 265 266 String mDesc = Type.getMethodDescriptor(m); 268 269 CodeVisitor cv = this.classGenerator.visitMethod(flags, m.getName(), mDesc, null, null); return cv; 276 } 277 278 protected void createUnwrappingCode(CodeVisitor cv, Class c) { 279 if (c == Void.TYPE) { 283 cv.visitInsn(POP); 284 } else if (c.isPrimitive()) { 285 String type; 286 String meth; 287 String desc; 288 if (c == Byte.TYPE) { 289 type = "java/lang/Byte"; 290 meth = "byteValue"; 291 desc = "B"; 292 } else if (c == Integer.TYPE) { 293 type = "java/lang/Integer"; 294 meth = "intValue"; 295 desc = "I"; 296 } else if (c == Boolean.TYPE) { 297 type = "java/lang/Boolean"; 298 meth = "booleanValue"; 299 desc = "Z"; 300 } else if (c == Double.TYPE) { 301 type = "java/lang/Double"; 302 meth = "doubleValue"; 303 desc = "D"; 304 } else if (c == Float.TYPE) { 305 type = "java/lang/Float"; 306 meth = "floatValue"; 307 desc = "F"; 308 } else if (c == Long.TYPE) { 309 type = "java/lang/Long"; 310 meth = "longValue"; 311 desc = "J"; 312 } else if (c == Character.TYPE) { 313 type = "java/lang/Character"; 314 meth = "charValue"; 315 desc = "C"; 316 } else 317 { 318 type = "java/lang/Short"; 319 meth = "shortValue"; 320 desc = "S"; 321 } 322 cv.visitTypeInsn(CHECKCAST, type); 323 cv.visitMethodInsn(INVOKEVIRTUAL, type, meth, "()" + desc); 324 } else { 325 cv.visitTypeInsn(CHECKCAST, Type.getInternalName(c)); 326 } 327 328 return; 329 } 330 331 protected void createReturnCode(CodeVisitor cv, Class c) { 332 if (c == Void.TYPE) { 333 cv.visitInsn(RETURN); 334 } else if (c.isPrimitive()) { 335 int opcode; 336 if (c == Double.TYPE) { 337 opcode = DRETURN; 338 } else if (c == Float.TYPE) { 339 opcode = FRETURN; 340 } else if (c == Long.TYPE) { 341 opcode = LRETURN; 342 } else { 343 opcode = IRETURN; 344 } 345 cv.visitInsn(opcode); 346 } else { 347 cv.visitInsn(ARETURN); 348 } 349 } 350 351 362 protected int getOpcodeOffset(final Class type) { 363 if (type == Double.TYPE) { 364 return 3; 365 } else if (type == Float.TYPE) { 366 return 2; 367 } else if (type == Long.TYPE) { 368 return 1; 369 } else if (type.isPrimitive()) { 370 return 0; 371 } 372 return 4; 373 } 374 375 382 protected int getSize(final Class type) { 383 return (((type == Double.TYPE) || (type == Long.TYPE)) ? 2 : 1); 384 } 385 386 protected Class defineClass(final String className, final byte[] bytes) { 387 try { 389 Class clc = Class.forName("java.lang.ClassLoader"); 390 Class [] argumentTypes = new Class [4]; 391 argumentTypes[0] = className.getClass(); 392 argumentTypes[1] = bytes.getClass(); 393 argumentTypes[2] = Integer.TYPE; 394 argumentTypes[3] = Integer.TYPE; 395 396 Method method = clc.getDeclaredMethod("defineClass", argumentTypes); 397 method.setAccessible(true); 398 399 Object [] effectiveArguments = new Object [4]; 400 effectiveArguments[0] = className; 401 effectiveArguments[1] = bytes; 402 effectiveArguments[2] = new Integer (0); 403 effectiveArguments[3] = new Integer (bytes.length); 404 405 return (Class ) method.invoke(Thread.currentThread().getContextClassLoader(), effectiveArguments); 406 } catch (ClassNotFoundException cnfe) { 407 cnfe.printStackTrace(); 408 409 throw new ProActiveRuntimeException(cnfe.toString()); 411 } catch (NoSuchMethodException nsme) { 412 nsme.printStackTrace(); 413 414 throw new ProActiveRuntimeException(nsme.toString()); 416 } catch (IllegalAccessException iae) { 417 iae.printStackTrace(); 418 throw new ProActiveRuntimeException(iae.toString()); 419 } catch (InvocationTargetException ite) { 420 ite.printStackTrace(); 421 throw new ProActiveRuntimeException(ite.toString()); 422 } 423 } 424 425 protected Class loadClass(final String className) throws ClassNotFoundException { 426 return Thread.currentThread().getContextClassLoader().loadClass(className); 428 } 429 430 433 protected void setInfos() throws ClassNotFoundException { 434 Vector tempVector = new Vector (); 436 Class [] params; 437 Object exists; 438 439 442 for (int j = 0; j < interfacesToImplement.size(); j++) { 443 Class interface_class = (Class ) interfacesToImplement.get(j); 445 Method [] allPublicMethods = interface_class.getMethods(); 446 for (int i = 0; i < allPublicMethods.length; i++) { 447 tempVector.addElement(allPublicMethods[i]); 448 } 449 } 450 451 this.methods = new Method [tempVector.size()]; 453 tempVector.copyInto(this.methods); 454 455 Vector v = new Vector (); 459 int initialNumberOfMethods = this.methods.length; 460 461 for (int i = 0; i < initialNumberOfMethods; i++) { 462 if (org.objectweb.proactive.core.mop.Utils.checkMethod(this.methods[i])) { 463 v.addElement(this.methods[i]); 464 } 465 } 466 467 Method [] validMethods = new Method [v.size()]; 468 v.copyInto(validMethods); 469 470 471 this.methods = validMethods; 473 474 475 this.packageName = null; 476 this.stubClassSimpleName = org.objectweb.proactive.core.mop.Utils.getSimpleName(this.stubClassFullName); 477 478 return; 479 } 480 } | Popular Tags |