|
8 | 8 | import java.lang.reflect.Field;
|
9 | 9 | import java.lang.reflect.Method;
|
10 | 10 | import java.lang.reflect.Modifier;
|
| 11 | +import java.lang.reflect.AccessibleObject; |
11 | 12 | import java.net.MalformedURLException;
|
12 | 13 | import java.net.URL;
|
13 | 14 | import java.net.URLClassLoader;
|
@@ -398,17 +399,31 @@ protected void createShorthandDispatchers(ClassContext c) {
|
398 | 399 |
|
399 | 400 | if (in_ent.getValue().size() == 1) {
|
400 | 401 | String desc = in_ent.getValue().iterator().next();
|
401 |
| - Method tobind = c.methods.get(shortname + "/" + desc); |
402 | 402 |
|
403 |
| - Class<?>[] ptype = tobind.getParameterTypes(); |
404 |
| - boolean isStatic = Modifier.isStatic(tobind.getModifiers()); |
405 |
| - |
406 |
| - int parix = 1; |
407 |
| - preMarshalIn(mc, tobind.getReturnType(), 0); |
408 |
| - if (!isStatic) marshalOut(mc, tobind.getDeclaringClass(), 0); |
409 |
| - for (Class<?> pt : ptype) marshalOut(mc, pt, parix++); |
410 |
| - mv.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, Type.getInternalName(tobind.getDeclaringClass()), tobind.getName(), desc); |
411 |
| - marshalIn(mc, tobind.getReturnType(), 0); |
| 403 | + try { |
| 404 | + // is it a method or a constructor? |
| 405 | + Method tobind = (Method)c.methods.get(shortname + "/" + desc); |
| 406 | + Class<?>[] ptype = tobind.getParameterTypes(); |
| 407 | + boolean isStatic = Modifier.isStatic(tobind.getModifiers()); |
| 408 | + |
| 409 | + int parix = 1; |
| 410 | + preMarshalIn(mc, tobind.getReturnType(), 0); |
| 411 | + if (!isStatic) marshalOut(mc, tobind.getDeclaringClass(), 0); |
| 412 | + for (Class<?> pt : ptype) marshalOut(mc, pt, parix++); |
| 413 | + mv.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, Type.getInternalName(tobind.getDeclaringClass()), tobind.getName(), desc); |
| 414 | + marshalIn(mc, tobind.getReturnType(), 0); |
| 415 | + } |
| 416 | + catch(ClassCastException ex) { |
| 417 | + Constructor tobind = (Constructor)c.methods.get(shortname + "/" + desc); |
| 418 | + Class<?>[] ptypes = tobind.getParameterTypes(); |
| 419 | + int parix = 1; |
| 420 | + preMarshalIn(mc, tobind.getDeclaringClass(), 0); |
| 421 | + mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(tobind.getDeclaringClass())); |
| 422 | + mv.visitInsn(Opcodes.DUP); |
| 423 | + for (Class<?> p : ptypes) marshalOut(mc, p, parix++); |
| 424 | + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(tobind.getDeclaringClass()), "<init>", desc); |
| 425 | + marshalIn(mc, tobind.getDeclaringClass(), 0); |
| 426 | + } |
412 | 427 |
|
413 | 428 | mv.visitJumpInsn(Opcodes.GOTO, finish);
|
414 | 429 | } else {
|
@@ -539,6 +554,18 @@ protected void createAdaptorField(ClassContext c, Field f) {
|
539 | 554 | protected void createAdaptorConstructor(ClassContext c, Constructor<?> k) {
|
540 | 555 | Class<?>[] ptypes = k.getParameterTypes();
|
541 | 556 | String desc = Type.getConstructorDescriptor(k);
|
| 557 | + Integer arity = ptypes.length; |
| 558 | + String name = "new"; |
| 559 | + |
| 560 | + if (!c.arities.containsKey(name)) { |
| 561 | + c.arities.put(name, new HashMap<Integer, List<String>>()); |
| 562 | + } |
| 563 | + if (!c.arities.get(name).containsKey(arity)) { |
| 564 | + c.arities.get(name).put(arity, new ArrayList<String>()); |
| 565 | + } |
| 566 | + c.arities.get(name).get(arity).add(desc); |
| 567 | + // stash the method away for later generation of shorthand methods. |
| 568 | + c.methods.put(name + "/" + desc, k); |
542 | 569 | MethodContext cc = startCallout(c, ptypes.length + 1, "constructor/new/"+desc);
|
543 | 570 | int parix = 1;
|
544 | 571 | preMarshalIn(cc, k.getDeclaringClass(), 0);
|
@@ -805,7 +832,7 @@ protected static class ClassContext {
|
805 | 832 | /** Method name to arities to descriptors */
|
806 | 833 | public HashMap<String, HashMap<Integer, List<String>>> arities = new HashMap< >();
|
807 | 834 | /** Method descriptor to Method object */
|
808 |
| - public HashMap<String, Method> methods = new HashMap< >(); |
| 835 | + public HashMap<String, AccessibleObject> methods = new HashMap< >(); |
809 | 836 | /** The next qb_NNN index to use. */
|
810 | 837 | public int nextCallout;
|
811 | 838 | }
|
|
0 commit comments