-
Notifications
You must be signed in to change notification settings - Fork 226
Expand file tree
/
Copy pathClassMethodExposer.java
More file actions
73 lines (63 loc) · 2.54 KB
/
ClassMethodExposer.java
File metadata and controls
73 lines (63 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package org.python.expose.generate;
import org.objectweb.asm.Type;
import org.python.core.PyBuiltinClassMethodNarrow;
public class ClassMethodExposer extends MethodExposer {
private final Type[] actualArgs;
public ClassMethodExposer(Type onType,
int access,
String methodName,
String desc,
String typeName,
String[] asNames,
String[] defaults,
String doc) {
super(onType,
methodName,
getArgs(onType, methodName, desc),
Type.getReturnType(desc),
typeName,
asNames,
defaults,
PyBuiltinClassMethodNarrow.class,
doc);
actualArgs = Type.getArgumentTypes(desc);
}
private static Type[] getArgs(Type onType, String methodName, String desc) {
Type[] args = Type.getArgumentTypes(desc);
boolean needsThreadState = needsThreadState(args);
int offset = needsThreadState ? 1 : 0;
if (args.length == offset || !args[offset].equals(PYTYPE)) {
String msg = String.format("ExposedClassMethod's first argument %smust be "
+ "PyType[method=%s.%s]",
needsThreadState ? "(following ThreadState) " : "",
onType.getClassName(), methodName);
throw new InvalidExposingException(msg);
}
// Remove PyType from the exposed __call__'s args, it'll be already bound as self
Type[] filledInArgs = new Type[args.length - 1];
if (needsThreadState) {
// ThreadState precedes PyType
filledInArgs[0] = args[0];
System.arraycopy(args, 2, filledInArgs, 1, filledInArgs.length - 1);
} else {
System.arraycopy(args, 1, filledInArgs, 0, filledInArgs.length);
}
return filledInArgs;
}
@Override
protected void makeCall() {
callStatic(onType, methodName, returnType, actualArgs);
}
@Override
protected void checkSelf() {
mv.visitTypeInsn(CHECKCAST, PYTYPE.getInternalName());
}
@Override
protected void loadSelfAndThreadState() {
// ThreadState precedes self for ClassMethods, load it first if necessary
loadThreadState();
// Push self on the stack so we can call it
get("self", PYOBJ);
checkSelf();
}
}