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:
igor%mir2.org 2004-11-17 16:48:57 +00:00
Родитель af61b217ff
Коммит 4b3a0cd41a
1 изменённых файлов: 77 добавлений и 69 удалений

Просмотреть файл

@ -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;
}