Generate a delegate method - static or instance. The generated code packs the method arguments into an object array (wrapping primitive types in bsh.Primitive), invokes the static or instance namespace invokeMethod() method, and then unwraps / returns the result.
(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw)
| 316 | * the result. |
| 317 | */ |
| 318 | private static void generateMethod(String className, String fqClassName, String methodName, String returnType, String[] paramTypes, int modifiers, ClassWriter cw) { |
| 319 | String[] exceptions = null; |
| 320 | boolean isStatic = (modifiers & ACC_STATIC) != 0; |
| 321 | |
| 322 | if (returnType == null) // map loose return type to Object |
| 323 | { |
| 324 | returnType = OBJECT; |
| 325 | } |
| 326 | |
| 327 | String methodDescriptor = getMethodDescriptor(returnType, paramTypes); |
| 328 | |
| 329 | // Generate method body |
| 330 | CodeVisitor cv = cw.visitMethod(modifiers, methodName, methodDescriptor, exceptions); |
| 331 | |
| 332 | if ((modifiers & ACC_ABSTRACT) != 0) { |
| 333 | return; |
| 334 | } |
| 335 | |
| 336 | // Generate code to push the BSHTHIS or BSHSTATIC field |
| 337 | if (isStatic) { |
| 338 | cv.visitFieldInsn(GETSTATIC, fqClassName, BSHSTATIC + className, "Lbsh/This;"); |
| 339 | } else { |
| 340 | // Push 'this' |
| 341 | cv.visitVarInsn(ALOAD, 0); |
| 342 | |
| 343 | // Get the instance field |
| 344 | cv.visitFieldInsn(GETFIELD, fqClassName, BSHTHIS + className, "Lbsh/This;"); |
| 345 | } |
| 346 | |
| 347 | // Push the name of the method as a constant |
| 348 | cv.visitLdcInsn(methodName); |
| 349 | |
| 350 | // Generate code to push arguments as an object array |
| 351 | generateParameterReifierCode(paramTypes, isStatic, cv); |
| 352 | |
| 353 | // Push nulls for various args of invokeMethod |
| 354 | cv.visitInsn(ACONST_NULL); // interpreter |
| 355 | cv.visitInsn(ACONST_NULL); // callstack |
| 356 | cv.visitInsn(ACONST_NULL); // callerinfo |
| 357 | |
| 358 | // Push the boolean constant 'true' (for declaredOnly) |
| 359 | cv.visitInsn(ICONST_1); |
| 360 | |
| 361 | // Invoke the method This.invokeMethod( name, Class [] sig, boolean ) |
| 362 | cv.visitMethodInsn(INVOKEVIRTUAL, "bsh/This", "invokeMethod", Type.getMethodDescriptor(Type.getType(Object.class), new Type[]{Type.getType(String.class), Type.getType(Object[].class), Type.getType(Interpreter.class), Type.getType(CallStack.class), Type.getType(SimpleNode.class), Type.getType(Boolean.TYPE)})); |
| 363 | |
| 364 | // Generate code to unwrap bsh Primitive types |
| 365 | cv.visitMethodInsn(INVOKESTATIC, "bsh/Primitive", "unwrap", "(Ljava/lang/Object;)Ljava/lang/Object;"); |
| 366 | |
| 367 | // Generate code to return the value |
| 368 | generateReturnCode(returnType, cv); |
| 369 | |
| 370 | // Need to calculate this... just fudging here for now. |
| 371 | cv.visitMaxs(20, 20); |
| 372 | } |
| 373 | |
| 374 | |
| 375 | /** |
no test coverage detected