Fixed for problems caused by r1555. The problem was that doing an arrayList.add(Element) would not wrap the element going into JSNI, and the object would fail a dynamic type check upon retrieval.
The solution is to actually do the wrapping exactly when the declared type of the parameter passing into JSNI is not JavaScriptObject or a subclass. We comply by making it a valid Java Object. If the declared type is JSO or a subclass, then there's no reason to wrap.
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1571 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectCaster.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectCaster.java
index 3ca1a6f..b4f0a7c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectCaster.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectCaster.java
@@ -103,18 +103,14 @@
ArrayList<JExpression> args = x.getArgs();
JMethod target = x.getTarget();
- /*
- * Check arguments for calls to non-native methods. Do not check native
- * invocations because we're losing all static type information anyway.
- */
- if (!target.isNative()) {
- for (int i = 0; i < target.params.size(); ++i) {
- JParameter param = target.params.get(i);
- JExpression arg = args.get(i);
- JExpression newArg = checkAndReplaceJso(arg, param.getType());
- this.didChange |= (newArg != arg);
- args.set(i, newArg);
- }
+
+ for (int i = 0; i < target.params.size(); ++i) {
+ JParameter param = target.params.get(i);
+ JExpression arg = args.get(i);
+ JExpression newArg = checkAndReplaceJso(arg, param.getType(),
+ target.isNative());
+ this.didChange |= (newArg != arg);
+ args.set(i, newArg);
}
/*
@@ -168,10 +164,15 @@
return true;
}
+ private JExpression checkAndReplaceJso(JExpression arg, JType targetType) {
+ return checkAndReplaceJso(arg, targetType, false);
+ }
+
/**
* Wraps a JSO-typed argument if the target type is a different type.
*/
- private JExpression checkAndReplaceJso(JExpression arg, JType targetType) {
+ private JExpression checkAndReplaceJso(JExpression arg, JType targetType,
+ boolean nowrapJso) {
JType argType = arg.getType();
if (argType == targetType) {
return arg;
@@ -182,6 +183,15 @@
if (!program.isJavaScriptObject(argType)) {
return arg;
}
+ /*
+ * Special case: when calling a native method, only force a wrapping if
+ * the type is explicitly Object. As long as the target type is a JSO
+ * subclass, don't bother wrapping since we're losing type information
+ * anyway.
+ */
+ if (nowrapJso && program.isJavaScriptObject(targetType)) {
+ return arg;
+ }
// Synthesize a cast to the arg type to force a wrap
JCastOperation cast = new JCastOperation(program, arg.getSourceInfo(),
argType, arg);