Providing JavaScript specific implementations of Hashtable and Vector. Those should likely be faster for the JavaScript VM than interpreting bytecode. This is the way to get the best of JavaScript and yet provide reasonably well working implementation in Java.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 13 Dec 2012 23:20:47 +0100
changeset 3168da329789435
parent 315 fc52cbbcbeb9
child 317 15cbc8cb2163
child 318 5876fdbbca11
Providing JavaScript specific implementations of Hashtable and Vector. Those should likely be faster for the JavaScript VM than interpreting bytecode. This is the way to get the best of JavaScript and yet provide reasonably well working implementation in Java.
core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java
javap/src/main/java/org/apidesign/javap/Hashtable.java
javap/src/main/java/org/apidesign/javap/Vector.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
     1.1 --- a/core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java	Thu Dec 13 08:43:52 2012 +0100
     1.2 +++ b/core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java	Thu Dec 13 23:20:47 2012 +0100
     1.3 @@ -29,10 +29,13 @@
     1.4  @Target({ ElementType.TYPE })
     1.5  public @interface JavaScriptPrototype {
     1.6      /** Expression that identifies the function where all methods
     1.7 -     * should be added into.
     1.8 +     * should be added into. If this attribute is unspecified
     1.9 +     * all methods are added to the same object specified by
    1.10 +     * {@link #prototype()}.
    1.11 +     * 
    1.12       * @return name of function to contain methods found in given class
    1.13       */
    1.14 -    String container();
    1.15 +    String container() default "";
    1.16      /** Expression that defines the way to construct prototype for this
    1.17       * class.
    1.18       * @return expression to construct prototype
     2.1 --- a/javap/src/main/java/org/apidesign/javap/Hashtable.java	Thu Dec 13 08:43:52 2012 +0100
     2.2 +++ b/javap/src/main/java/org/apidesign/javap/Hashtable.java	Thu Dec 13 23:20:47 2012 +0100
     2.3 @@ -4,6 +4,8 @@
     2.4   */
     2.5  package org.apidesign.javap;
     2.6  
     2.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     2.8 +
     2.9  /** A JavaScript optimized replacement for Hashtable.
    2.10   *
    2.11   * @author Jaroslav Tulach <jtulach@netbeans.org>
    2.12 @@ -23,6 +25,9 @@
    2.13      Hashtable() {
    2.14      }
    2.15  
    2.16 +    @JavaScriptBody(args = { "self", "key", "val" }, body = 
    2.17 +        "self[key] = val;"
    2.18 +    )
    2.19      synchronized void put(Object key, Object val) {
    2.20          int[] where = { -1, -1 };
    2.21          Object found = get(key, where);
    2.22 @@ -56,6 +61,9 @@
    2.23          }
    2.24      }
    2.25  
    2.26 +    @JavaScriptBody(args = {"self", "key" }, body = 
    2.27 +        "return self[key];"
    2.28 +    )
    2.29      Object get(Object key) {
    2.30          return get(key, null);
    2.31      }
     3.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java	Thu Dec 13 08:43:52 2012 +0100
     3.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java	Thu Dec 13 23:20:47 2012 +0100
     3.3 @@ -4,10 +4,14 @@
     3.4   */
     3.5  package org.apidesign.javap;
     3.6  
     3.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     3.8 +import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
     3.9 +
    3.10  /** A JavaScript ready replacement for java.util.Vector
    3.11   *
    3.12   * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.13   */
    3.14 +@JavaScriptPrototype(prototype = "new Array" )
    3.15  final class Vector {
    3.16      private Object[] arr;
    3.17      
    3.18 @@ -15,22 +19,31 @@
    3.19      }
    3.20  
    3.21      Vector(int i) {
    3.22 -        this();
    3.23      }
    3.24  
    3.25      void add(Object objectType) {
    3.26          addElement(objectType);
    3.27      }
    3.28 +    @JavaScriptBody(args = { "self", "obj" }, body = 
    3.29 +        "self.push(obj);"
    3.30 +    )
    3.31      void addElement(Object obj) {
    3.32          final int s = size();
    3.33          setSize(s + 1);
    3.34          setElementAt(obj, s);
    3.35      }
    3.36  
    3.37 +    @JavaScriptBody(args = { "self" }, body = 
    3.38 +        "return self.length;"
    3.39 +    )
    3.40      int size() {
    3.41          return arr == null ? 0 : arr.length;
    3.42      }
    3.43  
    3.44 +    @JavaScriptBody(args = { "self", "newArr" }, body =
    3.45 +        "for (var i = 0; i < self.length; i++) {\n"
    3.46 +      + "  newArr[i] = self[i];\n"
    3.47 +      + "}\n")
    3.48      void copyInto(Object[] newArr) {
    3.49          if (arr == null) {
    3.50              return;
    3.51 @@ -41,16 +54,22 @@
    3.52          }
    3.53      }
    3.54  
    3.55 +    @JavaScriptBody(args = { "self", "index" }, body =
    3.56 +        "return self[index];"
    3.57 +    )
    3.58      Object elementAt(int index) {
    3.59          return arr[index];
    3.60      }
    3.61  
    3.62 -    void setSize(int len) {
    3.63 +    private void setSize(int len) {
    3.64          Object[] newArr = new Object[len];
    3.65          copyInto(newArr);
    3.66          arr = newArr;
    3.67      }
    3.68  
    3.69 +    @JavaScriptBody(args = { "self", "val", "index" }, body = 
    3.70 +        "self[index] = val;"
    3.71 +    )
    3.72      void setElementAt(Object val, int index) {
    3.73          arr[index] = val;
    3.74      }
     4.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Dec 13 08:43:52 2012 +0100
     4.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Dec 13 23:20:47 2012 +0100
     4.3 @@ -109,6 +109,9 @@
     4.4              out.append("\n    var sprcls = pp.constructor.$class;");
     4.5          } else {
     4.6              out.append("\n    var p = CLS.prototype = ").append(proto[1]).append(";");
     4.7 +            if (proto[0] == null) {
     4.8 +                proto[0] = "p";
     4.9 +            }
    4.10              out.append("\n    var c = ").append(proto[0]).append(";");
    4.11              out.append("\n    var sprcls = null;");
    4.12          }
    4.13 @@ -1081,8 +1084,7 @@
    4.14          String space;
    4.15          int index;
    4.16          if (!isStatic) {                
    4.17 -            out.append(p.args[0]);
    4.18 -            space = ",";
    4.19 +            space = outputArg(out, p.args, 0);
    4.20              index = 1;
    4.21          } else {
    4.22              space = "";
    4.23 @@ -1090,9 +1092,8 @@
    4.24          }
    4.25          for (int i = 0; i < cnt.length(); i++) {
    4.26              out.append(space);
    4.27 -            out.append(p.args[index]);
    4.28 +            space = outputArg(out, p.args, index);
    4.29              index++;
    4.30 -            space = ",";
    4.31          }
    4.32          out.append(") {").append("\n");
    4.33          out.append(p.body);
    4.34 @@ -1184,4 +1185,16 @@
    4.35          };
    4.36          ap.parse(data, cd);
    4.37      }
    4.38 +
    4.39 +    private static String outputArg(Appendable out, String[] args, int indx) throws IOException {
    4.40 +        final String name = args[indx];
    4.41 +        if (name == null) {
    4.42 +            return "";
    4.43 +        }
    4.44 +        if (name.contains(",")) {
    4.45 +            throw new IOException("Wrong parameter with ',': " + name);
    4.46 +        }
    4.47 +        out.append(name);
    4.48 +        return ",";
    4.49 +    }
    4.50  }