On Fri, Jan 8, 2010 at 3:11 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Thu, Jan 7, 2010 at 6:48 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Thu, Jan 7, 2010 at 11:37 AM, Alessio Stalla alessiostalla@gmail.com wrote:
On Thu, Jan 7, 2010 at 4:32 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Thu, Jan 7, 2010 at 6:39 AM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
At this point, we can either
- ignore the problem,
- always call setAccessible(true) before calling a method,
- try to find the overridden method as up as possible in the class
hierarchy before calling it, hoping to get at some point to a public class/interface
- and 3. would make all method calls through jcall less efficient;
however, we could enable one of those techniques only when some additional parameter is passed to jcall (e.g. the try-harder that was proposed some time ago for jfield).
Bye, Ale
I believe that the code that jss uses a method cache and therefore only needs to do the setAccessible call once. Have you looked at what jsint.Invoke does or considered simply adopting it for ABCL?
http://jscheme.sourceforge.net/jscheme/doc/api/jsint/Invoke.html
We designed the following solution:
every Java object (instance of JavaObject) carries a reference to its "intended class", which must be a supertype of the object's class. The intended class is used to access the object's methods via reflection; only if a method is not found in the intended class the more specific object class is used, and only if it's public.
How is the intended class determined? There are two possibilities:
- automatically, by looking at the method return type (for objects
returned by a method call), field type (for objects read from a field), or class of the object (when it is constructed explicitly with jnew)
- manually, through a new operator - (jcoerce obj class)
The automatic way covers the common case of methods returning an instance of a class or interface implemented via a non-public inner class, which was the source of the bug.
For more complex cases - for example when an object is an instance like the above but implements several different interfaces, and must be accessed specifically through one of them, which might not be the one that has been chosen automatically - jcoerce comes to help.
This patch is now applied on trunk (rev. 12345) and you are encouraged to try it and comment on it.
I haven't benchmarked it, but I don't expect a performance degradation, just a slightly increased memory usage due to the extra reference to the intended class stored in every JavaObject.
Bye, Alessio
Will try, however:
abcl.compile.java: [javac] Compiling 273 source files to /Users/alanr/repos/abcl1/build/classes [javac] /Users/alanr/repos/abcl1/src/org/armedbear/lisp/Java.java:677: cannot find symbol [javac] symbol : constructor WrongNumberOfArgumentsException(java.lang.String) [javac] location: class org.armedbear.lisp.WrongNumberOfArgumentsException [javac] return error(new WrongNumberOfArgumentsException("Wrong number of arguments for " + method + ": expected " + argTypes.length + ", got " + (args.length - 2))); [javac] ^ [javac] Note: /Users/alanr/repos/abcl1/src/org/armedbear/lisp/JavaObject.java uses unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details.
Kind of curious: Why are you not just using the jsint implementation? It's been in use for quite a while and it would certainly make my life easier to be able to continue to use that interface. For example, I use their findMethod implementation to get a method so I can optimize certain loops by avoiding dynamic lookup each time.
-Alan