src.org.python.expose.generate.ClassMethodExposer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
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();
}
}