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);