We are now handling the concept of Java arrays created in JSNI, sort of.  In our own JRE, it's sometimes useful to create a half-baked JS array, but use it as a normal array in Java code.  This change adds first-class support for this concept by rescuing/instantiating when passed into Java from JavaScript: String[], arrays of JSO subclasses, and arrays of primitive types.  This allows for some JRE efficiencies if you're careful; LongLib takes advantage of this now.

Review by: spoon (desk check)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2297 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 7a6a619..6fb1a31 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -425,11 +425,8 @@
       return false;
     }
 
-    private <T extends CanBeStatic & HasEnclosingType> boolean pruneViaNoninstantiability(
-        boolean isInstantiated, T it) {
-      if (it.getEnclosingType() == program.getIndexedType("Array")) {
-        return false;
-      }
+    private boolean pruneViaNoninstantiability(boolean isInstantiated,
+        CanBeStatic it) {
       return (!isInstantiated && !it.isStatic());
     }
   }
@@ -472,6 +469,8 @@
         }
       }
 
+      // Rescue the base Array type
+      rescue(program.getIndexedType("Array"), true, isInstantiated);
       return false;
     }
 
@@ -762,8 +761,24 @@
      * @see com.google.gwt.core.client.JavaScriptObject
      */
     private void maybeRescueJavaScriptObjectPassingIntoJava(JType type) {
+      boolean doIt = false;
       if (program.isJavaScriptObject(type)
-          || type == program.getTypeJavaLangObject()) {
+          || type == program.getTypeJavaLangString()) {
+        doIt = true;
+      } else if (type instanceof JArrayType) {
+        /*
+         * Hackish: in our own JRE we sometimes create "not quite baked" arrays
+         * in JavaScript for expediency.
+         */
+        JArrayType arrayType = (JArrayType) type;
+        JType elementType = arrayType.getElementType();
+        if (elementType instanceof JPrimitiveType
+            || elementType == program.getTypeJavaLangString()
+            || program.isJavaScriptObject(elementType)) {
+          doIt = true;
+        }
+      }
+      if (doIt) {
         rescue((JReferenceType) type, true, true);
       }
     }
@@ -821,12 +836,13 @@
     private void rescueByConcat(JType type) {
       JClassType stringType = program.getTypeJavaLangString();
       JPrimitiveType charType = program.getTypePrimitiveChar();
-      if (type instanceof JReferenceType && type != stringType) {
+      if (type instanceof JReferenceType && type != stringType
+          && type != program.getTypeNull()) {
         /*
          * Any reference types (except String, which works by default) that take
          * part in a concat must rescue java.lang.Object.toString().
          * 
-         * TODO: can we narrow the focus by walking up the type heirarchy or
+         * TODO: can we narrow the focus by walking up the type hierarchy or
          * doing explicit toString calls?
          */
         JMethod toStringMethod = program.getIndexedMethod("Object.toString");
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java
index ec7103a..d6b7b20 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java
@@ -22,10 +22,8 @@
 import com.google.gwt.dev.jjs.ast.JInterfaceType;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodBody;
-import com.google.gwt.dev.jjs.ast.JNullType;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.jjs.ast.JType;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
 import com.google.gwt.dev.util.TextOutput;
 
@@ -147,15 +145,6 @@
   }
 
   @Override
-  protected void printTypeName(JType type) {
-    if (type instanceof JNullType) {
-      print("Object");
-    } else {
-      super.printTypeName(type);
-    }
-  }
-
-  @Override
   protected boolean shouldPrintMethodBody() {
     return true;
   }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
index 4d0c755..926fdec 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
@@ -17,18 +17,17 @@
 
 import com.google.gwt.dev.jjs.ast.CanBeAbstract;
 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JArrayRef;
 import com.google.gwt.dev.jjs.ast.JBinaryOperation;
 import com.google.gwt.dev.jjs.ast.JBinaryOperator;
 import com.google.gwt.dev.jjs.ast.JCastOperation;
 import com.google.gwt.dev.jjs.ast.JClassType;
+import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JField;
 import com.google.gwt.dev.jjs.ast.JFieldRef;
 import com.google.gwt.dev.jjs.ast.JInstanceOf;
 import com.google.gwt.dev.jjs.ast.JInterfaceType;
 import com.google.gwt.dev.jjs.ast.JLocal;
-import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
 import com.google.gwt.dev.jjs.ast.JLocalRef;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodCall;
@@ -97,19 +96,6 @@
   public class FixDanglingRefsVisitor extends JModVisitor {
 
     @Override
-    public void endVisit(JArrayRef x, Context ctx) {
-      JExpression instance = x.getInstance();
-      if (instance.getType() == typeNull) {
-        if (!instance.hasSideEffects()) {
-          instance = program.getLiteralNull();
-        }
-        JArrayRef arrayRef = new JArrayRef(program, x.getSourceInfo(),
-            instance, program.getLiteralInt(0));
-        ctx.replaceMe(arrayRef);
-      }
-    }
-
-    @Override
     public void endVisit(JFieldRef x, Context ctx) {
       JExpression instance = x.getInstance();
       boolean isStatic = x.getField().isStatic();
diff --git a/dev/core/super/com/google/gwt/lang/LongLib.java b/dev/core/super/com/google/gwt/lang/LongLib.java
index 66fe1aa..ec03903 100644
--- a/dev/core/super/com/google/gwt/lang/LongLib.java
+++ b/dev/core/super/com/google/gwt/lang/LongLib.java
@@ -453,15 +453,6 @@
     return makeFromBits(highBits(a) ^ highBits(b), lowBits(a) ^ lowBits(b));
   }
 
-  /**
-   * Because this is a code gen type, this function will keep the double[] type
-   * from being pruned during optimizations. If double[] gets pruned, bad stuff
-   * happens.
-   */
-  static double[] saveDoubleArrayFromPruning() {
-    return new double[2];
-  }
-
   static long toLong(double[] a) {
     return (long) a[HIGH] + (long) a[LOW];
   }