mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
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.
This commit is contained in:
parent
2e8911c94f
commit
3a40845319
@ -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 <tt>cl</tt> 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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user