Skip to content

Commit

Permalink
WIP: first demo of 0-arg ctor callable from java getClass().newInstan…
Browse files Browse the repository at this point in the history
…ce()
  • Loading branch information
byteit101 committed Oct 2, 2020
1 parent c580a1a commit ab2ccf6
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public static RubyClass createConcreteJavaProxy(final ThreadContext context) {
return ConcreteJavaProxy;
}

///jcreates site
private static final class InitializeMethod extends org.jruby.internal.runtime.methods.JavaMethod {

private final CallSite jcreateSite = MethodIndex.getFunctionalCallSite("__jcreate!");
Expand Down
38 changes: 31 additions & 7 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

Expand Down Expand Up @@ -632,33 +633,42 @@ public final IRubyObject call(ThreadContext context, IRubyObject self, RubyModul

final JavaProxyConstructor matching;
switch (constructors.length) {
case 1: matching = matchConstructor0ArityOne(context, constructors, arg0); break;
case 1:
case 2: matching = matchConstructor0ArityOne(context, constructors, arg0); break;
default: matching = matchConstructorArityOne(context, constructors, arg0);
}

JavaObject newObject = matching.newInstance(self, arg0);
return JavaUtilities.set_java_object(self, self, newObject);
}

@Override
@Override //TODO: ensure both sides are good
public final IRubyObject call(final ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
if (((JavaProxy) self).getObject() == null )
{
final int arity = args.length;
final JavaProxyConstructor[] constructors = getProxyClass(self).getConstructors();

final JavaProxyConstructor matching;
switch (constructors.length) {
case 1: matching = matchConstructor0(context, constructors, arity, args); break;
case 1:// IS this logic sound? or should we be more careful
case 2: matching = matchConstructor0(context, constructors, arity, args); break;
default: matching = matchConstructor(context, constructors, arity, args);
}

JavaObject newObject = matching.newInstance(self, args);
return JavaUtilities.set_java_object(self, self, newObject);
} else
{
return (IRubyObject) ((JavaProxy)self).dataGetStruct();
}
}

// assumes only 1 constructor exists!
// assumes only 1 *Ruby* constructor exists! (Filters out nonruby)
private JavaProxyConstructor matchConstructor0ArityOne(final ThreadContext context,
final JavaProxyConstructor[] constructors, final IRubyObject arg0) {
JavaProxyConstructor forArity = checkCallableForArity(1, constructors, 0);
int index = constructors[0].isExportable() ? 1 : 0;
JavaProxyConstructor forArity = checkCallableForArity(1, constructors, index);

if ( forArity == null ) {
throw context.runtime.newArgumentError("wrong number of arguments for constructor");
Expand All @@ -677,7 +687,8 @@ private JavaProxyConstructor matchConstructor0ArityOne(final ThreadContext conte
// assumes only 1 constructor exists!
private JavaProxyConstructor matchConstructor0(final ThreadContext context,
final JavaProxyConstructor[] constructors, final int arity, final IRubyObject[] args) {
JavaProxyConstructor forArity = checkCallableForArity(arity, constructors, 0);
int index = constructors[0].isExportable() ? 1 : 0;
JavaProxyConstructor forArity = checkCallableForArity(arity, constructors, index);

if ( forArity == null ) {
throw context.runtime.newArgumentError("wrong number of arguments for constructor");
Expand All @@ -696,6 +707,13 @@ private JavaProxyConstructor matchConstructor0(final ThreadContext context,
private JavaProxyConstructor matchConstructorArityOne(final ThreadContext context,
final JavaProxyConstructor[] constructors, final IRubyObject arg0) {
ArrayList<JavaProxyConstructor> forArity = findCallablesForArity(1, constructors);

// remove java-only methods
Iterator<JavaProxyConstructor> iter = forArity.iterator();
while (iter.hasNext()) {
if(iter.next().isExportable())
iter.remove();
}

if ( forArity.size() == 0 ) {
throw context.runtime.newArgumentError("wrong number of arguments for constructor");
Expand All @@ -716,10 +734,16 @@ private JavaProxyConstructor matchConstructor(final ThreadContext context,
final JavaProxyConstructor[] constructors, final int arity, final IRubyObject... args) {
ArrayList<JavaProxyConstructor> forArity = findCallablesForArity(arity, constructors);

// remove java-only methods
Iterator<JavaProxyConstructor> iter = forArity.iterator();
while (iter.hasNext()) {
if(iter.next().isExportable())
iter.remove();
}

if ( forArity.size() == 0 ) {
throw context.runtime.newArgumentError("wrong number of arguments for constructor");
}

final JavaProxyConstructor matching = CallableSelector.matchingCallableArityN(
context.runtime, this, forArity.toArray(new JavaProxyConstructor[forArity.size()]), args
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@

package org.jruby.javasupport.proxy;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.jruby.javasupport.proxy.JavaProxyClassFactory.ClassInvocationHolder;

/**
* Contains methods that are only called from generated code
*
Expand All @@ -43,5 +49,20 @@ public static JavaProxyMethod initProxyMethod(JavaProxyClass proxyClass,
String name, String desc, boolean hasSuper) {
return proxyClass.initMethod(name, desc, hasSuper);
}

private static Map<Integer, ClassInvocationHolder> defaultJpihs = new ConcurrentHashMap<>();

public static int sized()
{
return defaultJpihs.size();
}

public static ClassInvocationHolder getDefaultJPIH(int id) {
return defaultJpihs.remove(id);
}

public static void addDefaultJIPH(int id, ClassInvocationHolder jiph){
defaultJpihs.put(id, jiph);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public Class[] getInterfaces() {

private transient JavaProxyConstructor[] constructors;

// TODO: filter out in Java Jcreate or here?
public JavaProxyConstructor[] getConstructors() {
JavaProxyConstructor[] constructors = this.constructors;
if ( constructors != null ) return constructors;
Expand Down

0 comments on commit ab2ccf6

Please sign in to comment.