From 3a40845319a9b8ce9fee099059dd818707ea87d3 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Mon, 29 Aug 2005 19:27:17 +0000 Subject: [PATCH] Cleanup of JS function as Java interface implementation: 1. I removed caching of indicators of which types to convert: it just consumes extra memory without any noticeable benefits. 2. Better comments. --- .../mozilla/javascript/InterfaceAdapter.java | 38 +++++++------------ .../mozilla/javascript/NativeJavaObject.java | 23 ++++++----- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/js/rhino/src/org/mozilla/javascript/InterfaceAdapter.java b/js/rhino/src/org/mozilla/javascript/InterfaceAdapter.java index 172a7c5e0bee..63f5598ff733 100644 --- a/js/rhino/src/org/mozilla/javascript/InterfaceAdapter.java +++ b/js/rhino/src/org/mozilla/javascript/InterfaceAdapter.java @@ -44,7 +44,6 @@ import java.lang.reflect.Method; public class InterfaceAdapter { private final Object proxyHelper; - private boolean[] argsToConvert; /** * Make glue object implementing interface cl that will @@ -54,16 +53,16 @@ public class InterfaceAdapter * @return The glue object or null if cl is not interface or * has methods with different signatures. */ - static Object create(Context cx, Class cl, Callable f) + static Object create(Context cx, Class cl, Callable function) { + if (!cl.isInterface()) throw new IllegalArgumentException(); + Scriptable topScope = ScriptRuntime.getTopCallScope(cx); ClassCache cache = ClassCache.get(topScope); InterfaceAdapter adapter; adapter = (InterfaceAdapter)cache.getInterfaceAdapter(cl); ContextFactory cf = cx.getFactory(); if (adapter == null) { - if (!cl.isInterface()) - return null; Method[] methods = cl.getMethods(); if (methods.length == 0) { return null; } Class returnType = methods[0].getReturnType(); @@ -78,26 +77,18 @@ public class InterfaceAdapter } } - adapter = new InterfaceAdapter(cf, cl, argTypes); + adapter = new InterfaceAdapter(cf, cl); cache.cacheInterfaceAdapter(cl, adapter); } return VMBridge.instance.newInterfaceProxy( - adapter.proxyHelper, cf, adapter, f, topScope); + adapter.proxyHelper, cf, adapter, function, topScope); } - private InterfaceAdapter(ContextFactory cf, Class cl, Class[] argTypes) + private InterfaceAdapter(ContextFactory cf, Class cl) { this.proxyHelper = VMBridge.instance.getInterfaceProxyHelper( cf, new Class[] { cl }); - for (int i = 0; i != argTypes.length; ++i) { - if (!ScriptRuntime.isRhinoRuntimeType(argTypes[i])) { - if (argsToConvert == null) { - argsToConvert = new boolean[argTypes.length]; - } - argsToConvert[i] = true; - } - } } public Object invoke(ContextFactory cf, @@ -121,24 +112,21 @@ public class InterfaceAdapter Method method, Object[] args) { - Callable callable = (Callable)target; int N = (args == null) ? 0 : args.length; + String methodName = method.getName(); + + Callable function = (Callable)target; + Scriptable thisObj = topScope; Object[] jsargs = new Object[N + 1]; - if (N != 0) { - System.arraycopy(args, 0, jsargs, 0, N); - } jsargs[N] = method.getName(); - if (argsToConvert != null) { + if (N != 0) { WrapFactory wf = cx.getWrapFactory(); for (int i = 0; i != N; ++i) { - if (argsToConvert[i]) { - jsargs[i] = wf.wrap(cx, topScope, jsargs[i], null); - } + jsargs[i] = wf.wrap(cx, topScope, args[i], null); } } - Scriptable thisObj = topScope; - Object result = callable.call(cx, topScope, thisObj, jsargs); + Object result = function.call(cx, topScope, thisObj, jsargs); Class javaResultType = method.getReturnType(); if (javaResultType == Void.TYPE) { result = null; diff --git a/js/rhino/src/org/mozilla/javascript/NativeJavaObject.java b/js/rhino/src/org/mozilla/javascript/NativeJavaObject.java index 177b0111a2be..72a5ca766104 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeJavaObject.java +++ b/js/rhino/src/org/mozilla/javascript/NativeJavaObject.java @@ -661,17 +661,15 @@ WrapFactory#wrap(Context cx, Scriptable scope, Object obj, Class)} reportConversionError(value, type); } else if (type.isInterface() && value instanceof Callable) { - // Try to wrap function into interface with single method. - Callable callable = (Function)value; - - // Can not wrap generic Callable since the resulting object - // should be reused next time conversion is made - // and generic Function has no storage for it. - // Weak referencesfrom JDK 1.2 can address it, but for now - // restrict the conversion only to classes extending from - // ScriptableObject to use associateValue for storage - if (callable instanceof ScriptableObject) { - ScriptableObject so = (ScriptableObject)callable; + // Try to use function as implementation of Java interface. + // + // XXX: Curently only instances of ScriptableObject are + // supported since the resulting interface proxies should + // be reused next time conversion is made and generic + // Callable has no storage for it. Weak references can + // address it but for now use this restriction. + if (value instanceof ScriptableObject) { + ScriptableObject so = (ScriptableObject)value; Object key = Kit.makeHashKeyFromPair( COERCED_INTERFACE_KEY, type); Object old = so.getAssociatedValue(key); @@ -680,7 +678,8 @@ WrapFactory#wrap(Context cx, Scriptable scope, Object obj, Class)} return old; } Context cx = Context.getContext(); - Object glue = InterfaceAdapter.create(cx, type, callable); + Object glue + = InterfaceAdapter.create(cx, type, (Callable)value); if (glue != null) { // Store for later retrival glue = so.associateValue(key, glue);