зеркало из https://github.com/mozilla/gecko-dev.git
For VARARG methods wrap the result in the same way as for other methods: in this way VARARG method returning non-JS-type will get its results properly wrapped as LiveConnect object
This commit is contained in:
Родитель
af61b217ff
Коммит
4b3a0cd41a
|
@ -46,8 +46,6 @@ import java.io.*;
|
|||
public class FunctionObject extends BaseFunction
|
||||
{
|
||||
|
||||
static final long serialVersionUID = -4074285335521944312L;
|
||||
|
||||
/**
|
||||
* Create a JavaScript function object from a Java method.
|
||||
*
|
||||
|
@ -386,70 +384,96 @@ public class FunctionObject extends BaseFunction
|
|||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
Object result;
|
||||
boolean checkMethodResult = false;
|
||||
|
||||
if (parmsLength < 0) {
|
||||
return callVarargs(cx, thisObj, args);
|
||||
}
|
||||
if (!isStatic) {
|
||||
Class clazz = member.getDeclaringClass();
|
||||
if (!clazz.isInstance(thisObj)) {
|
||||
boolean compatible = false;
|
||||
if (thisObj == scope) {
|
||||
Scriptable parentScope = getParentScope();
|
||||
if (scope != parentScope) {
|
||||
// Call with dynamic scope for standalone function,
|
||||
// use parentScope as thisObj
|
||||
compatible = clazz.isInstance(parentScope);
|
||||
if (compatible) {
|
||||
thisObj = parentScope;
|
||||
if (parmsLength == VARARGS_METHOD) {
|
||||
Object[] invokeArgs = { cx, thisObj, args, this };
|
||||
result = member.invoke(null, invokeArgs);
|
||||
checkMethodResult = true;
|
||||
} else {
|
||||
boolean inNewExpr = (thisObj == null);
|
||||
Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
|
||||
Object[] invokeArgs = { cx, args, this, b };
|
||||
result = (member.isCtor())
|
||||
? member.newInstance(invokeArgs)
|
||||
: member.invoke(null, invokeArgs);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!isStatic) {
|
||||
Class clazz = member.getDeclaringClass();
|
||||
if (!clazz.isInstance(thisObj)) {
|
||||
boolean compatible = false;
|
||||
if (thisObj == scope) {
|
||||
Scriptable parentScope = getParentScope();
|
||||
if (scope != parentScope) {
|
||||
// Call with dynamic scope for standalone function,
|
||||
// use parentScope as thisObj
|
||||
compatible = clazz.isInstance(parentScope);
|
||||
if (compatible) {
|
||||
thisObj = parentScope;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!compatible) {
|
||||
// Couldn't find an object to call this on.
|
||||
throw ScriptRuntime.typeError1("msg.incompat.call",
|
||||
functionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object[] invokeArgs;
|
||||
if (parmsLength == args.length) {
|
||||
// Do not allocate new argument array if java arguments are
|
||||
// the same as the original js ones.
|
||||
invokeArgs = args;
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = args[i];
|
||||
Object converted = convertArg(cx, scope, arg, typeTags[i]);
|
||||
if (arg != converted) {
|
||||
if (invokeArgs == args) {
|
||||
invokeArgs = (Object[])args.clone();
|
||||
if (!compatible) {
|
||||
// Couldn't find an object to call this on.
|
||||
throw ScriptRuntime.typeError1("msg.incompat.call",
|
||||
functionName);
|
||||
}
|
||||
invokeArgs[i] = converted;
|
||||
}
|
||||
}
|
||||
} else if (parmsLength == 0) {
|
||||
invokeArgs = ScriptRuntime.emptyArgs;
|
||||
} else {
|
||||
invokeArgs = new Object[parmsLength];
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = (i < args.length)
|
||||
? args[i]
|
||||
: Undefined.instance;
|
||||
invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
|
||||
|
||||
Object[] invokeArgs;
|
||||
if (parmsLength == args.length) {
|
||||
// Do not allocate new argument array if java arguments are
|
||||
// the same as the original js ones.
|
||||
invokeArgs = args;
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = args[i];
|
||||
Object converted = convertArg(cx, scope, arg, typeTags[i]);
|
||||
if (arg != converted) {
|
||||
if (invokeArgs == args) {
|
||||
invokeArgs = (Object[])args.clone();
|
||||
}
|
||||
invokeArgs[i] = converted;
|
||||
}
|
||||
}
|
||||
} else if (parmsLength == 0) {
|
||||
invokeArgs = ScriptRuntime.emptyArgs;
|
||||
} else {
|
||||
invokeArgs = new Object[parmsLength];
|
||||
for (int i = 0; i != parmsLength; ++i) {
|
||||
Object arg = (i < args.length)
|
||||
? args[i]
|
||||
: Undefined.instance;
|
||||
invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (member.isMethod()) {
|
||||
result = member.invoke(thisObj, invokeArgs);
|
||||
checkMethodResult = true;
|
||||
} else {
|
||||
result = member.newInstance(invokeArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object result;
|
||||
if (member.isMethod()) {
|
||||
result = member.invoke(thisObj, invokeArgs);
|
||||
if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
|
||||
if (checkMethodResult) {
|
||||
if (hasVoidReturn) {
|
||||
result = Undefined.instance;
|
||||
} else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
|
||||
result = cx.getWrapFactory().wrap(cx, scope, result, null);
|
||||
}
|
||||
} else {
|
||||
result = member.newInstance(invokeArgs);
|
||||
// XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE
|
||||
// then the Java method did a proper job of converting the
|
||||
// result to JS primitive or Scriptable to avoid
|
||||
// potentially costly Context.javaToJS call.
|
||||
}
|
||||
|
||||
return hasVoidReturn ? Undefined.instance : result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -474,22 +498,6 @@ public class FunctionObject extends BaseFunction
|
|||
return result;
|
||||
}
|
||||
|
||||
private Object callVarargs(Context cx, Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (parmsLength == VARARGS_METHOD) {
|
||||
Object[] invokeArgs = { cx, thisObj, args, this };
|
||||
Object result = member.invoke(null, invokeArgs);
|
||||
return hasVoidReturn ? Undefined.instance : result;
|
||||
} else {
|
||||
boolean inNewExpr = (thisObj == null);
|
||||
Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
|
||||
Object[] invokeArgs = { cx, args, this, b };
|
||||
return (member.isCtor())
|
||||
? member.newInstance(invokeArgs)
|
||||
: member.invoke(null, invokeArgs);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isVarArgsMethod() {
|
||||
return parmsLength == VARARGS_METHOD;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче