You're welcome. While I was at it, I discovered that, although the
Lisp-to-Java FFI
takes care of demarshalling booleans, it does not marshall them. That
is, when a
Lisp function calls a Java function, and the Java function returns a
boolean (of the
primitive Java type, not an instance of the class Boolean), it's
converted into t or nil.
However, when a Lisp function attempts to pass t or nil as an argument
to a Java
function, it's not handled; the loop that checks the arguments just
skips over it, which
I think results in passing the value "false"?
This actually places the would-be-developer in a worse situation than
if there were
neither marshalling nor demarshalling. If that were the case, it would
be possible to
obtain a true or false value, wrapped in a JAVAOBJECT, by calling some
function
with a known return value, then to save a copy of it, and pass it in
wherever desired.
The easy fix would be to add code to convert t and nil into true and
false, respectively,
whenever they are passed in. However, it is also desirable to allow
nil to represent
the null value. So ideally, the code would check the type of the
argument which the
constructor is expecting, and map nil to null for anything other than a
boolean. I lack
the familiarity with Java to implement this easily, though.
I've appended the patch I came up with. It implements the simple
fix, for booleans
only, and it changes jcall, jnew, and jstatic. I've tested all three
of those codepaths.
It is made against version 0.20.2.
Future work (I'm not volunteering! =D I just happened to have a
little time to spend on this)
might add support for allowing nil to represent null, and might factor
out the nearly-duplicated
code into a single, separate function for marshalling Lisp data, to
avoid possible inconsistency
bugs.
Hope this is useful.
-- Dan Knapp
diff /Users/dankna/bin/j-0.20.2/src/org/armedbear/lisp/Java.java.orig
/Users/dankna/bin/j-0.20.2/src/org/armedbear/lisp/Java.java
179a180,183
> else if (arg == T)
> methodArgs[i-2] = new Boolean(true);
> else if (arg instanceof Nil)
> methodArgs[i-2] = new Boolean(false);
209a214,217
> else if (arg == T)
> initargs[i-1] = new Boolean(true);
> else if (arg instanceof Nil)
> initargs[i-1] = new Boolean(false);
242a251,254
> else if (arg == T)
> methodArgs[i-2] = new Boolean(true);
> else if (arg instanceof Nil)
> methodArgs[i-2] = new Boolean(false);
Diff finished. Thu Aug 19 12:50:56 2004
|