Skip to content

Commit e81dec4

Browse files
committed
allow us to dispatch arity-based constructors
1 parent ba639c6 commit e81dec4

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

src/vm/jvm/runtime/org/perl6/nqp/runtime/BootJavaInterop.java

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.lang.reflect.Field;
99
import java.lang.reflect.Method;
1010
import java.lang.reflect.Modifier;
11+
import java.lang.reflect.AccessibleObject;
1112
import java.net.MalformedURLException;
1213
import java.net.URL;
1314
import java.net.URLClassLoader;
@@ -398,17 +399,31 @@ protected void createShorthandDispatchers(ClassContext c) {
398399

399400
if (in_ent.getValue().size() == 1) {
400401
String desc = in_ent.getValue().iterator().next();
401-
Method tobind = c.methods.get(shortname + "/" + desc);
402402

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+
}
412427

413428
mv.visitJumpInsn(Opcodes.GOTO, finish);
414429
} else {
@@ -539,6 +554,18 @@ protected void createAdaptorField(ClassContext c, Field f) {
539554
protected void createAdaptorConstructor(ClassContext c, Constructor<?> k) {
540555
Class<?>[] ptypes = k.getParameterTypes();
541556
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);
542569
MethodContext cc = startCallout(c, ptypes.length + 1, "constructor/new/"+desc);
543570
int parix = 1;
544571
preMarshalIn(cc, k.getDeclaringClass(), 0);
@@ -805,7 +832,7 @@ protected static class ClassContext {
805832
/** Method name to arities to descriptors */
806833
public HashMap<String, HashMap<Integer, List<String>>> arities = new HashMap< >();
807834
/** Method descriptor to Method object */
808-
public HashMap<String, Method> methods = new HashMap< >();
835+
public HashMap<String, AccessibleObject> methods = new HashMap< >();
809836
/** The next qb_NNN index to use. */
810837
public int nextCallout;
811838
}

0 commit comments

Comments
 (0)