[armedbear-cvs] r13259 - in trunk/abcl: . src/org/armedbear/lisp
Alessio Stalla
astalla at common-lisp.net
Sat Apr 2 21:56:06 UTC 2011
Author: astalla
Date: Sat Apr 2 17:56:04 2011
New Revision: 13259
Log:
Java method resolution algorithm used by JCALL extracted to a method and exposed as the Lisp function JAVA:JRESOLVE-METHOD
Modified:
trunk/abcl/pom.xml
trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java
trunk/abcl/src/org/armedbear/lisp/Java.java
trunk/abcl/src/org/armedbear/lisp/Symbol.java
trunk/abcl/src/org/armedbear/lisp/WrongNumberOfArgumentsException.java
Modified: trunk/abcl/pom.xml
==============================================================================
--- trunk/abcl/pom.xml (original)
+++ trunk/abcl/pom.xml Sat Apr 2 17:56:04 2011
@@ -13,7 +13,7 @@
</parent>
<groupId>org.armedbear.lisp</groupId>
<artifactId>abcl</artifactId>
- <version>0.25.0-SNAPSHOT</version>
+ <version>0.26.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ABCL - Armed Bear Common Lisp</name>
<description>Common Lisp implementation running on the JVM</description>
Modified: trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java Sat Apr 2 17:56:04 2011
@@ -105,16 +105,16 @@
}
public LispObject loadFunction(int fnNumber) {
+ //Function name is fnIndex + 1
+ String name = baseName + "_" + (fnNumber + 1);
try {
- //Function name is fnIndex + 1
- String name = baseName + "_" + (fnNumber + 1);
Function f = (Function) loadClass(name).newInstance();
f.setClassBytes(getFunctionClassBytes(name));
return f;
- } catch(Exception e) {
+ } catch(Throwable e) {
if(e instanceof ControlTransfer) { throw (ControlTransfer) e; }
Debug.trace(e);
- return error(new LispError("Compiled function can't be loaded: " + baseName + "_" + (fnNumber + 1) + " " + Symbol.LOAD_TRUENAME.symbolValue()));
+ return error(new LispError("Compiled function can't be loaded: " + name + " from " + Symbol.LOAD_TRUENAME.symbolValue()));
}
}
Modified: trunk/abcl/src/org/armedbear/lisp/Java.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Java.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/Java.java Sat Apr 2 17:56:04 2011
@@ -62,16 +62,16 @@
private static final Primitive ENSURE_JAVA_OBJECT = new pf_ensure_java_object();
@DocString(name="ensure-java-object", args="obj",
doc="Ensures OBJ is wrapped in a JAVA-OBJECT, wrapping it if necessary.")
- private static final class pf_ensure_java_object extends Primitive
+ private static final class pf_ensure_java_object extends Primitive
{
- pf_ensure_java_object()
+ pf_ensure_java_object()
{
super("ensure-java-object", PACKAGE_JAVA, true);
}
@Override
public LispObject execute(LispObject obj) {
- return obj instanceof JavaObject ? obj : new JavaObject(obj);
+ return obj instanceof JavaObject ? obj : new JavaObject(obj);
}
};
@@ -80,9 +80,9 @@
args="exception-name condition-symbol",
doc="Registers the Java Throwable named by the symbol EXCEPTION-NAME as the condition " +
"designated by CONDITION-SYMBOL. Returns T if successful, NIL if not.")
- private static final class pf_register_java_exception extends Primitive
+ private static final class pf_register_java_exception extends Primitive
{
- pf_register_java_exception()
+ pf_register_java_exception()
{
super("register-java-exception", PACKAGE_JAVA, true);
}
@@ -108,7 +108,7 @@
" by REGISTER-JAVA-EXCEPTION.")
private static final class pf_unregister_java_exception extends Primitive
{
- pf_unregister_java_exception()
+ pf_unregister_java_exception()
{
super("unregister-java-exception", PACKAGE_JAVA, true);
}
@@ -447,16 +447,16 @@
if (c != null) {
String methodName = methodRef.getStringValue();
Method[] methods = c.getMethods();
- List<Method> staticMethods = new ArrayList<Method>();
+ List<Method> staticMethods = new ArrayList<Method>();
int argCount = args.length - 2;
- for(Method m1 : methods) {
- if(Modifier.isStatic(m1.getModifiers())) {
- staticMethods.add(m1);
- }
- }
- if(staticMethods.size() > 0) {
- m = findMethod(staticMethods.toArray(new Method[staticMethods.size()]), methodName, args);
- }
+ for(Method m1 : methods) {
+ if(Modifier.isStatic(m1.getModifiers())) {
+ staticMethods.add(m1);
+ }
+ }
+ if(staticMethods.size() > 0) {
+ m = findMethod(staticMethods.toArray(new Method[staticMethods.size()]), methodName, args, 2);
+ }
if (m == null)
error(new LispError("no such method"));
}
@@ -748,7 +748,7 @@
}
};
- /**
+ /**
* Does no type conversion. The result of the call is simply wrapped in a
* JavaObject.
*/
@@ -770,53 +770,86 @@
}
};
+ private static final Primitive JRESOLVE_METHOD = new pf_jresolve_method();
+ @DocString(name="jresolve_method", args="method-name instance &rest args",
+ doc="Finds the most specific Java method METHOD-NAME on INSTANCE " +
+ "applicable to arguments ARGS. Returns NIL if no suitable method is " +
+ "found. The algorithm used for resolution is the same used by JCALL " +
+ "when it is called with a string as the first parameter (METHOD-REF).")
+ private static final class pf_jresolve_method extends Primitive {
+
+ pf_jresolve_method() {
+ super(Symbol.JRESOLVE_METHOD);
+ }
+
+ @Override
+ public LispObject execute(LispObject[] args) {
+ if (args.length < 2) {
+ error(new WrongNumberOfArgumentsException(this, 2));
+ }
+ final LispObject methodArg = args[0];
+ final LispObject instanceArg = args[1];
+ final Object instance;
+ Class<?> intendedClass = null;
+ if (instanceArg instanceof AbstractString) {
+ instance = instanceArg.getStringValue();
+ } else if (instanceArg instanceof JavaObject) {
+ JavaObject jobj = ((JavaObject)instanceArg);
+ instance = jobj.getObject();
+ intendedClass = jobj.getIntendedClass();
+ } else {
+ instance = instanceArg.javaInstance();
+ }
+ if(instance == null) {
+ return error(new ProgramError("JRESOLVE-METHOD: instance must not be null"));
+ }
+ String methodName = methodArg.getStringValue();
+ Object[] methodArgs = translateMethodArguments(args, 2);
+ Method method = findMethod(instance, intendedClass, methodName, methodArgs);
+ if (method != null) {
+ return JavaObject.getInstance(method);
+ } else {
+ return NIL;
+ }
+ }
+ };
+
static LispObject jcall(Primitive fun, LispObject[] args, boolean translate)
{
if (args.length < 2)
- error(new WrongNumberOfArgumentsException(fun));
+ error(new WrongNumberOfArgumentsException(fun, 2));
try {
- final LispObject methodArg = args[0];
- final LispObject instanceArg = args[1];
- final Object instance;
- Class<?> intendedClass = null;
- if (instanceArg instanceof AbstractString) {
- instance = instanceArg.getStringValue();
- } else if (instanceArg instanceof JavaObject) {
- JavaObject jobj = ((JavaObject)instanceArg);
- instance = jobj.getObject();
- intendedClass = jobj.getIntendedClass();
- } else {
- instance = instanceArg.javaInstance();
- }
- if(instance == null) {
- throw new NullPointerException(); //Handled below
- }
+ final LispObject methodArg = args[0];
+ final LispObject instanceArg = args[1];
+ final Object instance;
Method method;
- Object[] methodArgs;
+ Object[] methodArgs;
+ Class<?> intendedClass = null;
+ if (instanceArg instanceof AbstractString) {
+ instance = instanceArg.getStringValue();
+ } else if (instanceArg instanceof JavaObject) {
+ JavaObject jobj = ((JavaObject)instanceArg);
+ instance = jobj.getObject();
+ intendedClass = jobj.getIntendedClass();
+ } else {
+ instance = instanceArg.javaInstance();
+ }
+ if(instance == null) {
+ throw new NullPointerException(); //Handled below
+ }
if (methodArg instanceof AbstractString) {
- methodArgs = translateMethodArguments(args, 2);
String methodName = methodArg.getStringValue();
- if(intendedClass == null) {
- intendedClass = instance.getClass();
- }
- method = findMethod(intendedClass, methodName, methodArgs);
- Class actualClass = null;
- if(method == null) {
- actualClass = instance.getClass();
- if(intendedClass != actualClass &&
- Modifier.isPublic(actualClass.getModifiers())) {
- method = findMethod(actualClass, methodName, methodArgs);
- }
- }
- if (method == null) {
- String classes = intendedClass.getName();
- if(actualClass != null && actualClass != intendedClass) {
- classes += " or " + actualClass.getName();
- }
- throw new NoSuchMethodException("No applicable method named " + methodName + " found in " + classes);
- }
-
+ methodArgs = translateMethodArguments(args, 2);
+ method = findMethod(instance, intendedClass, methodName, methodArgs);
+ if (method == null) {
+ String classes = intendedClass.getName();
+ Class<?> actualClass = instance.getClass();
+ if(actualClass != intendedClass) {
+ classes += " or " + actualClass.getName();
+ }
+ throw new NoSuchMethodException("No applicable method named " + methodName + " found in " + classes);
+ }
} else
method = (Method) JavaObject.getObject(methodArg);
Class<?>[] argTypes = (Class<?>[])method.getParameterTypes();
@@ -833,7 +866,7 @@
}
return JavaObject.getInstance(method.invoke(instance, methodArgs),
translate,
- method.getReturnType());
+ method.getReturnType());
}
catch (ControlTransfer t) {
throw t;
@@ -875,7 +908,7 @@
}
private static Method findMethod(Method[] methods, String methodName, Object[] javaArgs) {
- int argCount = javaArgs.length;
+ int argCount = javaArgs.length;
Method result = null;
for (int i = methods.length; i-- > 0;) {
Method method = methods[i];
@@ -896,23 +929,39 @@
return result;
}
+ private static Method findMethod(Object instance, Class<?> intendedClass, String methodName, Object[] methodArgs) {
+ if(intendedClass == null) {
+ intendedClass = instance.getClass();
+ }
+ Method method = findMethod(intendedClass, methodName, methodArgs);
+ Class actualClass = null;
+ if(method == null) {
+ actualClass = instance.getClass();
+ if(intendedClass != actualClass &&
+ Modifier.isPublic(actualClass.getModifiers())) {
+ method = findMethod(actualClass, methodName, methodArgs);
+ }
+ }
+ return method;
+ }
+
private static Method findMethod(Class<?> c, String methodName, Object[] javaArgs) {
Method[] methods = c.getMethods();
- return findMethod(methods, methodName, javaArgs);
+ return findMethod(methods, methodName, javaArgs);
}
- private static Method findMethod(Class<?> c, String methodName, LispObject[] args) {
- Object[] javaArgs = translateMethodArguments(args, 2);
- return findMethod(c, methodName, javaArgs);
+ private static Method findMethod(Class<?> c, String methodName, LispObject[] args, int offset) {
+ Object[] javaArgs = translateMethodArguments(args, offset);
+ return findMethod(c, methodName, javaArgs);
}
- private static Method findMethod(Method[] methods, String methodName, LispObject[] args) {
- Object[] javaArgs = translateMethodArguments(args, 2);
- return findMethod(methods, methodName, javaArgs);
+ private static Method findMethod(Method[] methods, String methodName, LispObject[] args, int offset) {
+ Object[] javaArgs = translateMethodArguments(args, offset);
+ return findMethod(methods, methodName, javaArgs);
}
static Constructor findConstructor(Class<?> c, LispObject[] args) throws NoSuchMethodException {
- int argCount = args.length - 1;
+ int argCount = args.length - 1;
Object[] javaArgs = translateMethodArguments(args, 1);
Constructor[] ctors = c.getConstructors();
Constructor result = null;
Modified: trunk/abcl/src/org/armedbear/lisp/Symbol.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Symbol.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/Symbol.java Sat Apr 2 17:56:04 2011
@@ -2970,7 +2970,7 @@
public static final Symbol JAVA_OBJECT =
PACKAGE_JAVA.addExternalSymbol("JAVA-OBJECT");
public static final Symbol JAVA_CLASS =
- PACKAGE_JAVA.addExternalSymbol("JAVA-CLASS");
+ PACKAGE_JAVA.addExternalSymbol("JAVA-CLASS");
public static final Symbol JCALL =
PACKAGE_JAVA.addExternalSymbol("JCALL");
public static final Symbol JCALL_RAW =
@@ -2983,6 +2983,8 @@
PACKAGE_JAVA.addExternalSymbol("JCLASS-OF");
public static final Symbol JMETHOD_RETURN_TYPE =
PACKAGE_JAVA.addExternalSymbol("JMETHOD-RETURN-TYPE");
+ public static final Symbol JRESOLVE_METHOD =
+ PACKAGE_JAVA.addExternalSymbol("JRESOLVE-METHOD");
// External symbols in SYSTEM package.
public static final Symbol _ENABLE_AUTOCOMPILE_ =
Modified: trunk/abcl/src/org/armedbear/lisp/WrongNumberOfArgumentsException.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/WrongNumberOfArgumentsException.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/WrongNumberOfArgumentsException.java Sat Apr 2 17:56:04 2011
@@ -42,7 +42,7 @@
private String message;
public WrongNumberOfArgumentsException(Operator operator) {
- this(operator, -1);
+ this(operator, -1);
}
public WrongNumberOfArgumentsException(Operator operator, int expectedArgs) {
More information about the armedbear-cvs
mailing list