# HG changeset patch # User Jaroslav Tulach # Date 1355437247 -3600 # Node ID 8da329789435be467c110affcbe01165ea1a9c33 # Parent fc52cbbcbeb917a4d437f1cbd7276bffa6546c07 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. diff -r fc52cbbcbeb9 -r 8da329789435 core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java --- a/core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java Thu Dec 13 08:43:52 2012 +0100 +++ b/core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java Thu Dec 13 23:20:47 2012 +0100 @@ -29,10 +29,13 @@ @Target({ ElementType.TYPE }) public @interface JavaScriptPrototype { /** Expression that identifies the function where all methods - * should be added into. + * should be added into. If this attribute is unspecified + * all methods are added to the same object specified by + * {@link #prototype()}. + * * @return name of function to contain methods found in given class */ - String container(); + String container() default ""; /** Expression that defines the way to construct prototype for this * class. * @return expression to construct prototype diff -r fc52cbbcbeb9 -r 8da329789435 javap/src/main/java/org/apidesign/javap/Hashtable.java --- a/javap/src/main/java/org/apidesign/javap/Hashtable.java Thu Dec 13 08:43:52 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/Hashtable.java Thu Dec 13 23:20:47 2012 +0100 @@ -4,6 +4,8 @@ */ package org.apidesign.javap; +import org.apidesign.bck2brwsr.core.JavaScriptBody; + /** A JavaScript optimized replacement for Hashtable. * * @author Jaroslav Tulach @@ -23,6 +25,9 @@ Hashtable() { } + @JavaScriptBody(args = { "self", "key", "val" }, body = + "self[key] = val;" + ) synchronized void put(Object key, Object val) { int[] where = { -1, -1 }; Object found = get(key, where); @@ -56,6 +61,9 @@ } } + @JavaScriptBody(args = {"self", "key" }, body = + "return self[key];" + ) Object get(Object key) { return get(key, null); } diff -r fc52cbbcbeb9 -r 8da329789435 javap/src/main/java/org/apidesign/javap/Vector.java --- a/javap/src/main/java/org/apidesign/javap/Vector.java Thu Dec 13 08:43:52 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java Thu Dec 13 23:20:47 2012 +0100 @@ -4,10 +4,14 @@ */ package org.apidesign.javap; +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.apidesign.bck2brwsr.core.JavaScriptPrototype; + /** A JavaScript ready replacement for java.util.Vector * * @author Jaroslav Tulach */ +@JavaScriptPrototype(prototype = "new Array" ) final class Vector { private Object[] arr; @@ -15,22 +19,31 @@ } Vector(int i) { - this(); } void add(Object objectType) { addElement(objectType); } + @JavaScriptBody(args = { "self", "obj" }, body = + "self.push(obj);" + ) void addElement(Object obj) { final int s = size(); setSize(s + 1); setElementAt(obj, s); } + @JavaScriptBody(args = { "self" }, body = + "return self.length;" + ) int size() { return arr == null ? 0 : arr.length; } + @JavaScriptBody(args = { "self", "newArr" }, body = + "for (var i = 0; i < self.length; i++) {\n" + + " newArr[i] = self[i];\n" + + "}\n") void copyInto(Object[] newArr) { if (arr == null) { return; @@ -41,16 +54,22 @@ } } + @JavaScriptBody(args = { "self", "index" }, body = + "return self[index];" + ) Object elementAt(int index) { return arr[index]; } - void setSize(int len) { + private void setSize(int len) { Object[] newArr = new Object[len]; copyInto(newArr); arr = newArr; } + @JavaScriptBody(args = { "self", "val", "index" }, body = + "self[index] = val;" + ) void setElementAt(Object val, int index) { arr[index] = val; } diff -r fc52cbbcbeb9 -r 8da329789435 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Dec 13 08:43:52 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Dec 13 23:20:47 2012 +0100 @@ -109,6 +109,9 @@ out.append("\n var sprcls = pp.constructor.$class;"); } else { out.append("\n var p = CLS.prototype = ").append(proto[1]).append(";"); + if (proto[0] == null) { + proto[0] = "p"; + } out.append("\n var c = ").append(proto[0]).append(";"); out.append("\n var sprcls = null;"); } @@ -1081,8 +1084,7 @@ String space; int index; if (!isStatic) { - out.append(p.args[0]); - space = ","; + space = outputArg(out, p.args, 0); index = 1; } else { space = ""; @@ -1090,9 +1092,8 @@ } for (int i = 0; i < cnt.length(); i++) { out.append(space); - out.append(p.args[index]); + space = outputArg(out, p.args, index); index++; - space = ","; } out.append(") {").append("\n"); out.append(p.body); @@ -1184,4 +1185,16 @@ }; ap.parse(data, cd); } + + private static String outputArg(Appendable out, String[] args, int indx) throws IOException { + final String name = args[indx]; + if (name == null) { + return ""; + } + if (name.contains(",")) { + throw new IOException("Wrong parameter with ',': " + name); + } + out.append(name); + return ","; + } }