Skip to content

Commit

Permalink
painless: add method overloading based on arity
Browse files Browse the repository at this point in the history
Closes #18385

Squashed commit of the following:

commit b2819df4d392d69b86e5c96d358eb03424e67e02
Author: Robert Muir <rmuir@apache.org>
Date:   Tue May 17 09:15:47 2016 -0400

    add note about tuple

commit 85fcac6
Author: Robert Muir <rmuir@apache.org>
Date:   Mon May 16 23:39:25 2016 -0400

    painless: add method overloading based on arity
  • Loading branch information
rmuir committed May 17, 2016
1 parent 8547410 commit 92339c4
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,37 +133,41 @@ static MethodHandle arrayLengthGetter(Class<?> arrayType) {
* <p>
* @param receiverClass Class of the object to invoke the method on.
* @param name Name of the method.
* @param type Callsite signature. Need not match exactly, except the number of parameters.
* @param definition Whitelist to check.
* @return pointer to matching method to invoke. never returns null.
* @throws IllegalArgumentException if no matching whitelisted method was found.
*/
static MethodHandle lookupMethod(Class<?> receiverClass, String name, Definition definition) {
// check whitelist for matching method
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
RuntimeClass struct = definition.runtimeMap.get(clazz);

if (struct != null) {
Method method = struct.methods.get(name);
if (method != null) {
return method.handle;
}
}

for (final Class<?> iface : clazz.getInterfaces()) {
struct = definition.runtimeMap.get(iface);

if (struct != null) {
Method method = struct.methods.get(name);
if (method != null) {
return method.handle;
}
}
}
}

// no matching methods in whitelist found
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] " +
"for class [" + receiverClass.getCanonicalName() + "].");
static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType type, Definition definition) {
// we don't consider receiver an argument/counting towards arity
type = type.dropParameterTypes(0, 1);
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
// check whitelist for matching method
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
RuntimeClass struct = definition.runtimeMap.get(clazz);

if (struct != null) {
Method method = struct.methods.get(key);
if (method != null) {
return method.handle;
}
}

for (final Class<?> iface : clazz.getInterfaces()) {
struct = definition.runtimeMap.get(iface);

if (struct != null) {
Method method = struct.methods.get(key);
if (method != null) {
return method.handle;
}
}
}
}

// no matching methods in whitelist found
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] with signature [" + type + "] " +
"for class [" + receiverClass.getCanonicalName() + "].");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ static boolean checkClass(Class<?> clazz, Object receiver) {
/**
* Does a slow lookup against the whitelist.
*/
private static MethodHandle lookup(int flavor, Class<?> clazz, String name) {
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
switch(flavor) {
case METHOD_CALL:
return Def.lookupMethod(clazz, name, Definition.INSTANCE);
return Def.lookupMethod(clazz, name, type, Definition.INSTANCE);
case LOAD:
return Def.lookupGetter(clazz, name, Definition.INSTANCE);
case STORE:
Expand All @@ -115,7 +115,7 @@ Object fallback(Object[] args) throws Throwable {
final MethodType type = type();
final Object receiver = args[0];
final Class<?> receiverClass = receiver.getClass();
final MethodHandle target = lookup(flavor, receiverClass, name).asType(type);
final MethodHandle target = lookup(flavor, receiverClass, name, type).asType(type);

if (depth >= MAX_DEPTH) {
// revert to a vtable call
Expand Down
Loading

0 comments on commit 92339c4

Please sign in to comment.