Storing constructor function in last element of multidimensional array closure
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 06 May 2014 11:12:40 +0200
branchclosure
changeset 1535c02c6d409461
parent 1534 ca538fb33f48
child 1536 7f477a85dbff
Storing constructor function in last element of multidimensional array
rt/emul/mini/src/main/java/java/lang/reflect/Array.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java
     1.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Array.java	Tue May 06 10:08:42 2014 +0200
     1.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Array.java	Tue May 06 11:12:40 2014 +0200
     1.3 @@ -677,16 +677,20 @@
     1.4  //    private static native void log(Object m);
     1.5      
     1.6      @Exported
     1.7 -    private static Object multiNewArray(String sig, int[] dims, int index)
     1.8 +    private static Object multiNewArray(String sig, int[] dims, Object fn)
     1.9 +    throws IllegalArgumentException, NegativeArraySizeException {
    1.10 +        return multiNewArray(sig, dims, 0, fn);
    1.11 +    }
    1.12 +    private static Object multiNewArray(String sig, int[] dims, int index, Object fn)
    1.13      throws IllegalArgumentException, NegativeArraySizeException {
    1.14          if (dims.length == index + 1) {
    1.15 -            return newArray(sig.length() == 2, sig, null, dims[index]);
    1.16 +            return newArray(sig.length() == 2, sig, fn, dims[index]);
    1.17          }
    1.18          Object arr = newArray(false, sig, null, dims[index]);
    1.19          String compsig = sig.substring(1);
    1.20          int len = getLength(arr);
    1.21          for (int i = 0; i < len; i++) {
    1.22 -            setArray(arr, i, multiNewArray(compsig, dims, index + 1));
    1.23 +            setArray(arr, i, multiNewArray(compsig, dims, index + 1, fn));
    1.24          }
    1.25          return arr;
    1.26      }
     2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue May 06 10:08:42 2014 +0200
     2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue May 06 11:12:40 2014 +0200
     2.3 @@ -2147,9 +2147,14 @@
     2.4              dims.insert(1, smapper.popI());
     2.5          }
     2.6          dims.append(']');
     2.7 +        String fn = "null";
     2.8 +        if (typeName.charAt(dim) == 'L') {
     2.9 +            fn = "vm." + mangleClassName(typeName.substring(dim + 1, typeName.length() - 1));
    2.10 +        }
    2.11          emit(smapper, this, 
    2.12 -            "var @2 = Array.prototype['multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II']('@3', @1, 0);",
    2.13 -             dims.toString(), smapper.pushA(), typeName);
    2.14 +            "var @2 = Array.prototype['multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3ILjava_lang_Object_2']('@3', @1, @4);",
    2.15 +             dims.toString(), smapper.pushA(), typeName, fn
    2.16 +        );
    2.17          return i;
    2.18      }
    2.19  
     3.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Tue May 06 10:08:42 2014 +0200
     3.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Tue May 06 11:12:40 2014 +0200
     3.3 @@ -77,6 +77,7 @@
     3.4      }
     3.5      
     3.6      public static double sum() {
     3.7 +        disableClassForName();
     3.8          double sum = 0.0;
     3.9          for (Array[] row : arr()) {
    3.10              int indx = -1;
    3.11 @@ -111,7 +112,11 @@
    3.12      }
    3.13      
    3.14      public static String objectArrayClass() {
    3.15 -        return Object[].class.getName();
    3.16 +        enableClassForName(prevClassForName);
    3.17 +        prevClassForName = null;
    3.18 +        String s = Object[].class.getName();
    3.19 +        disableClassForName();
    3.20 +        return s;
    3.21      }
    3.22      
    3.23      public static boolean instanceOfArray(Object obj) {
    3.24 @@ -169,13 +174,29 @@
    3.25      }
    3.26      
    3.27      @JavaScriptBody(args = {  }, body = 
    3.28 -        "if (!vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2) throw 'forName not defined';\n"
    3.29 +        "var prev = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2;\n"
    3.30 +      + "if (!prev) throw 'forName not defined';\n"
    3.31        + "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2 = function(s) {\n"
    3.32        + "  throw 'Do not call me: ' + s;\n"
    3.33 -      + "};\n")
    3.34 -    private static void disableClassForName() {
    3.35 +      + "};\n"
    3.36 +      + "return prev;\n")
    3.37 +    private static Object disableClassForNameImpl() {
    3.38 +        return null;
    3.39      }
    3.40      
    3.41 +    private static void disableClassForName() {
    3.42 +        if (prevClassForName == null) {
    3.43 +            prevClassForName = disableClassForNameImpl();
    3.44 +        }
    3.45 +    }
    3.46 +    
    3.47 +    @JavaScriptBody(args = { "fn" }, body = 
    3.48 +        "if (fn !== null) vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2 = fn;"
    3.49 +    )
    3.50 +    private static void enableClassForName(Object fn) {
    3.51 +    }
    3.52 +    
    3.53 +    private static Object prevClassForName;
    3.54      public static String nameOfClonedComponent() {
    3.55          disableClassForName();
    3.56          Object[] intArr = new Integer[10];