Skip to content

Commit 85fcac6

Browse files
committed
painless: add method overloading based on arity
1 parent be0bbce commit 85fcac6

11 files changed

Lines changed: 300 additions & 90 deletions

File tree

modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -133,37 +133,41 @@ static MethodHandle arrayLengthGetter(Class<?> arrayType) {
133133
* <p>
134134
* @param receiverClass Class of the object to invoke the method on.
135135
* @param name Name of the method.
136+
* @param type Callsite signature. Need not match exactly, except the number of parameters.
136137
* @param definition Whitelist to check.
137138
* @return pointer to matching method to invoke. never returns null.
138139
* @throws IllegalArgumentException if no matching whitelisted method was found.
139140
*/
140-
static MethodHandle lookupMethod(Class<?> receiverClass, String name, Definition definition) {
141-
// check whitelist for matching method
142-
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
143-
RuntimeClass struct = definition.runtimeMap.get(clazz);
144-
145-
if (struct != null) {
146-
Method method = struct.methods.get(name);
147-
if (method != null) {
148-
return method.handle;
149-
}
150-
}
151-
152-
for (final Class<?> iface : clazz.getInterfaces()) {
153-
struct = definition.runtimeMap.get(iface);
154-
155-
if (struct != null) {
156-
Method method = struct.methods.get(name);
157-
if (method != null) {
158-
return method.handle;
159-
}
160-
}
161-
}
162-
}
163-
164-
// no matching methods in whitelist found
165-
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] " +
166-
"for class [" + receiverClass.getCanonicalName() + "].");
141+
static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType type, Definition definition) {
142+
// we don't consider receiver an argument/counting towards arity
143+
type = type.dropParameterTypes(0, 1);
144+
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
145+
// check whitelist for matching method
146+
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
147+
RuntimeClass struct = definition.runtimeMap.get(clazz);
148+
149+
if (struct != null) {
150+
Method method = struct.methods.get(key);
151+
if (method != null) {
152+
return method.handle;
153+
}
154+
}
155+
156+
for (final Class<?> iface : clazz.getInterfaces()) {
157+
struct = definition.runtimeMap.get(iface);
158+
159+
if (struct != null) {
160+
Method method = struct.methods.get(key);
161+
if (method != null) {
162+
return method.handle;
163+
}
164+
}
165+
}
166+
}
167+
168+
// no matching methods in whitelist found
169+
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] with signature [" + type + "] " +
170+
"for class [" + receiverClass.getCanonicalName() + "].");
167171
}
168172

169173
/**

modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ static boolean checkClass(Class<?> clazz, Object receiver) {
9191
/**
9292
* Does a slow lookup against the whitelist.
9393
*/
94-
private static MethodHandle lookup(int flavor, Class<?> clazz, String name) {
94+
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
9595
switch(flavor) {
9696
case METHOD_CALL:
97-
return Def.lookupMethod(clazz, name, Definition.INSTANCE);
97+
return Def.lookupMethod(clazz, name, type, Definition.INSTANCE);
9898
case LOAD:
9999
return Def.lookupGetter(clazz, name, Definition.INSTANCE);
100100
case STORE:
@@ -115,7 +115,7 @@ Object fallback(Object[] args) throws Throwable {
115115
final MethodType type = type();
116116
final Object receiver = args[0];
117117
final Class<?> receiverClass = receiver.getClass();
118-
final MethodHandle target = lookup(flavor, receiverClass, name).asType(type);
118+
final MethodHandle target = lookup(flavor, receiverClass, name, type).asType(type);
119119

120120
if (depth >= MAX_DEPTH) {
121121
// revert to a vtable call

0 commit comments

Comments
 (0)