Fixed a latent bug with long array initialization; the initial values were 0.0d rather than 0L.  Also optimized array instantiation for multi-dimensional arrays with only one non-absent dimension.

Review by: spoon (TBR)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2256 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
index a69996f..60161d5 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
@@ -80,10 +80,20 @@
 
       if (x.initializers != null) {
         processInitializers(x, ctx, type);
-      } else if (type.getDims() == 1) {
-        processDim(x, ctx, type);
       } else {
-        processDims(x, ctx, type);
+        int realDims = 0;
+        for (JExpression dim : x.dims) {
+          if (dim instanceof JAbsentArrayDimension) {
+            break;
+          }
+          ++realDims;
+        }
+        assert (realDims >= 1);
+        if (realDims == 1) {
+          processDim(x, ctx, type);
+        } else {
+          processDims(x, ctx, type, realDims);
+        }
       }
     }
 
@@ -92,7 +102,10 @@
      */
     private JIntLiteral getSeedTypeLiteralFor(JType type) {
       if (type instanceof JPrimitiveType) {
-        if (type == program.getTypePrimitiveBoolean()) {
+        if (type == program.getTypePrimitiveLong()) {
+          // The long type, thus 0L (index 3)
+          return program.getLiteralInt(3);
+        } else if (type == program.getTypePrimitiveBoolean()) {
           // The boolean type, thus false (index 2)
           return program.getLiteralInt(2);
         } else {
@@ -111,18 +124,18 @@
       JLiteral classLit = program.getLiteralClass(arrayType);
       JLiteral typeIdLit = program.getLiteralInt(program.getTypeId(arrayType));
       JLiteral queryIdLit = program.getLiteralInt(tryGetQueryId(arrayType));
-      JType leafType = arrayType.getLeafType();
       JExpression dim = x.dims.get(0);
-
+      JType elementType = arrayType.getElementType();
       call.getArgs().add(classLit);
       call.getArgs().add(typeIdLit);
       call.getArgs().add(queryIdLit);
       call.getArgs().add(dim);
-      call.getArgs().add(getSeedTypeLiteralFor(leafType));
+      call.getArgs().add(getSeedTypeLiteralFor(elementType));
       ctx.replaceMe(call);
     }
 
-    private void processDims(JNewArray x, Context ctx, JArrayType arrayType) {
+    private void processDims(JNewArray x, Context ctx, JArrayType arrayType,
+        int dims) {
       // override the type of the called method with the array's type
       JMethodCall call = new JMethodCall(program, x.getSourceInfo(), null,
           initDims, arrayType);
@@ -130,48 +143,29 @@
       JsonArray typeIdList = new JsonArray(program);
       JsonArray queryIdList = new JsonArray(program);
       JsonArray dimList = new JsonArray(program);
-      JType leafType = arrayType.getLeafType();
-      int outstandingDims = arrayType.getDims();
-      for (int i = 0; i < x.dims.size(); ++i) {
-        JExpression dim = x.dims.get(i);
-        if (dim instanceof JAbsentArrayDimension) {
-          break;
-        }
-
-        /*
-         * For each non-empty dimension, reduce the number of dims on the end
-         * type.
-         * 
-         * new int[2][ ][ ]->int[][]
-         * 
-         * new int[2][3][ ]->int[]
-         * 
-         * new int[2][3][4]->int
-         * 
-         */
-        JArrayType cur = program.getTypeArray(leafType, outstandingDims--);
+      JType cur = arrayType;
+      for (int i = 0; i < dims; ++i) {
+        // Walk down each type from most dims to least.
+        JArrayType curArrayType = (JArrayType) cur;
 
         JLiteral classLit = program.getLiteralClass(cur);
         classLitList.exprs.add(classLit);
 
-        JLiteral typeIdLit = program.getLiteralInt(program.getTypeId(cur));
+        JLiteral typeIdLit = program.getLiteralInt(program.getTypeId(curArrayType));
         typeIdList.exprs.add(typeIdLit);
 
-        JLiteral queryIdLit = program.getLiteralInt(tryGetQueryId(cur));
+        JLiteral queryIdLit = program.getLiteralInt(tryGetQueryId(curArrayType));
         queryIdList.exprs.add(queryIdLit);
 
-        dimList.exprs.add(dim);
+        dimList.exprs.add(x.dims.get(i));
+        cur = curArrayType.getElementType();
       }
-      JType targetType = leafType;
-      if (outstandingDims > 0) {
-        targetType = program.getTypeArray(targetType, outstandingDims);
-      }
-
       call.getArgs().add(classLitList);
       call.getArgs().add(typeIdList);
       call.getArgs().add(queryIdList);
       call.getArgs().add(dimList);
-      call.getArgs().add(getSeedTypeLiteralFor(targetType));
+      call.getArgs().add(program.getLiteralInt(dims));
+      call.getArgs().add(getSeedTypeLiteralFor(cur));
       ctx.replaceMe(call);
     }
 
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
index eb2874a..86adf44 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
@@ -27,6 +27,8 @@
 
   static final int FALSE_SEED_TYPE = 2;
 
+  static final int LONG_SEED_TYPE = 3;
+
   static final int NULL_SEED_TYPE = 0;
 
   static final int ZERO_SEED_TYPE = 1;
@@ -90,9 +92,9 @@
    * @return the new array
    */
   public static Array initDims(Class arrayClasses[], int[] typeIdExprs,
-      int[] queryIdExprs, int[] dimExprs, int seedType) {
+      int[] queryIdExprs, int[] dimExprs, int count, int seedType) {
     return initDims(arrayClasses, typeIdExprs, queryIdExprs, dimExprs, 0,
-        dimExprs.length, seedType);
+        count, seedType);
   }
 
   /**
@@ -161,7 +163,7 @@
    * @return the new JSON array
    */
   private static native Array createFromSeed(int seedType, int length) /*-{
-    var seedArray = [null, 0, false];
+    var seedArray = [null, 0, false, [0, 0]];
     var value = seedArray[seedType];
     var array = new Array(length);
     for (var i = 0; i < length; ++i) {
@@ -173,10 +175,6 @@
   private static Array initDims(Class arrayClasses[], int[] typeIdExprs,
       int[] queryIdExprs, int[] dimExprs, int index, int count, int seedType) {
     int length = dimExprs[index];
-    if (length < 0) {
-      throw new NegativeArraySizeException();
-    }
-
     boolean isLastDim = (index == (count - 1));
 
     Array result = createFromSeed(isLastDim ? seedType : NULL_SEED_TYPE, length);
diff --git a/user/test/com/google/gwt/dev/jjs/test/NativeLongTest.java b/user/test/com/google/gwt/dev/jjs/test/NativeLongTest.java
index 3d2aabd..a45de61 100644
--- a/user/test/com/google/gwt/dev/jjs/test/NativeLongTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/NativeLongTest.java
@@ -60,6 +60,13 @@
     assertEquals(-1089359682551557853L, LONG_DEADBEEF % LONG_1234);
   }
 
+  public void testArrayInitializer() {
+    long[] longs = new long[3];
+    assertEquals(longs[1], 0L);
+    long[][] longs2 = new long[3][3];
+    assertEquals(longs2[1][1], 0L);
+  }
+
   public void testCasts() {
     assertEquals(0x12341234, (int) LONG_1234);
     assertEquals(0x1234, (short) LONG_1234);
@@ -102,14 +109,6 @@
     assertTrue(15 == l);
   }
 
-  public void testModifyingOps() {
-    long l = 20;
-    l += 10;
-    assertEquals(31, ++l);
-    assertEquals(31, l++);
-    assertEquals(32, l);
-  }
-
   public void testLogicalAnd() {
     assertEquals(LONG_1234, LONG_1234 & -LONG_ONE);
     assertEquals(0x12341234L, LONG_1234 & LONG_FFFFFFFF);
@@ -133,6 +132,14 @@
     assertEquals(2L, LONG_ONE ^ LONG_THREE);
   }
 
+  public void testModifyingOps() {
+    long l = 20;
+    l += 10;
+    assertEquals(31, ++l);
+    assertEquals(31, l++);
+    assertEquals(32, l);
+  }
+
   public void testShift() {
     assertEquals(LONG_5DEECE66D, LONG_5DEECE66D & ((LONG_ONE << 48) - 1));
     assertEquals(LONG_ONE << 12, (LONG_ONE << 60) >>> (48));