Merge with recent advances in default branch dew
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 16 Jan 2013 12:27:53 +0100
branchdew
changeset 467c50c541368f8
parent 466 d6b1f996c0d8
parent 459 a2871a3fd4c5
child 468 a7ff47e054f3
Merge with recent advances in default branch
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
pom.xml
     1.1 --- a/core/pom.xml	Wed Jan 16 12:25:50 2013 +0100
     1.2 +++ b/core/pom.xml	Wed Jan 16 12:27:53 2013 +0100
     1.3 @@ -19,8 +19,8 @@
     1.4                  <artifactId>maven-compiler-plugin</artifactId>
     1.5                  <version>2.3.2</version>
     1.6                  <configuration>
     1.7 -                    <source>1.6</source>
     1.8 -                    <target>1.6</target>
     1.9 +                    <source>1.7</source>
    1.10 +                    <target>1.7</target>
    1.11                  </configuration>
    1.12              </plugin>
    1.13          </plugins>
    1.14 @@ -35,6 +35,10 @@
    1.15        <version>3.8.1</version>
    1.16        <scope>test</scope>
    1.17      </dependency>
    1.18 +    <dependency>
    1.19 +      <groupId>org.netbeans.api</groupId>
    1.20 +      <artifactId>org-openide-util-lookup</artifactId>
    1.21 +    </dependency>
    1.22    </dependencies>
    1.23      <description>Contains esential annotations for associating JavaScript code with
    1.24  methods and classes.</description>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/core/src/main/java/org/apidesign/bck2brwsr/core/impl/JavaScriptProcesor.java	Wed Jan 16 12:27:53 2013 +0100
     2.3 @@ -0,0 +1,92 @@
     2.4 +/**
     2.5 + * Back 2 Browser Bytecode Translator
     2.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     2.7 + *
     2.8 + * This program is free software: you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License as published by
    2.10 + * the Free Software Foundation, version 2 of the License.
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program. Look for COPYING file in the top folder.
    2.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    2.20 + */
    2.21 +package org.apidesign.bck2brwsr.core.impl;
    2.22 +
    2.23 +import java.util.Collections;
    2.24 +import java.util.HashSet;
    2.25 +import java.util.List;
    2.26 +import java.util.Set;
    2.27 +import javax.annotation.processing.AbstractProcessor;
    2.28 +import javax.annotation.processing.Completion;
    2.29 +import javax.annotation.processing.Completions;
    2.30 +import javax.annotation.processing.Processor;
    2.31 +import javax.annotation.processing.RoundEnvironment;
    2.32 +import javax.lang.model.element.AnnotationMirror;
    2.33 +import javax.lang.model.element.Element;
    2.34 +import javax.lang.model.element.ElementKind;
    2.35 +import javax.lang.model.element.ExecutableElement;
    2.36 +import javax.lang.model.element.Modifier;
    2.37 +import javax.lang.model.element.TypeElement;
    2.38 +import javax.lang.model.element.VariableElement;
    2.39 +import javax.tools.Diagnostic;
    2.40 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    2.41 +import org.openide.util.lookup.ServiceProvider;
    2.42 +
    2.43 +/**
    2.44 + *
    2.45 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    2.46 + */
    2.47 +@ServiceProvider(service = Processor.class)
    2.48 +public final class JavaScriptProcesor extends AbstractProcessor {
    2.49 +    @Override
    2.50 +    public Set<String> getSupportedAnnotationTypes() {
    2.51 +        Set<String> set = new HashSet<>();
    2.52 +        set.add(JavaScriptBody.class.getName());
    2.53 +        return set;
    2.54 +    }
    2.55 +    
    2.56 +    @Override
    2.57 +    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    2.58 +        for (Element e : roundEnv.getElementsAnnotatedWith(JavaScriptBody.class)) {
    2.59 +            if (e.getKind() != ElementKind.METHOD && e.getKind() != ElementKind.CONSTRUCTOR) {
    2.60 +                continue;
    2.61 +            }
    2.62 +            ExecutableElement ee = (ExecutableElement)e;
    2.63 +            List<? extends VariableElement> params = ee.getParameters();
    2.64 +            
    2.65 +            JavaScriptBody jsb = e.getAnnotation(JavaScriptBody.class);
    2.66 +            String[] arr = jsb.args();
    2.67 +            if (params.size() != arr.length) {
    2.68 +                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Number of args arguments does not match real arguments!", e);
    2.69 +            }
    2.70 +        }
    2.71 +        return true;
    2.72 +    }
    2.73 +
    2.74 +    @Override
    2.75 +    public Iterable<? extends Completion> getCompletions(Element e, 
    2.76 +        AnnotationMirror annotation, ExecutableElement member, String userText
    2.77 +    ) {
    2.78 +        StringBuilder sb = new StringBuilder();
    2.79 +        if (e.getKind() == ElementKind.METHOD && member.getSimpleName().contentEquals("args")) {
    2.80 +            ExecutableElement ee = (ExecutableElement) e;
    2.81 +            String sep = "";
    2.82 +            sb.append("{ ");
    2.83 +            for (VariableElement ve : ee.getParameters()) {
    2.84 +                sb.append(sep).append('"').append(ve.getSimpleName())
    2.85 +                    .append('"');
    2.86 +                sep = ", ";
    2.87 +            }
    2.88 +            sb.append(" }");
    2.89 +            return Collections.nCopies(1, Completions.of(sb.toString()));
    2.90 +        }
    2.91 +        return null;
    2.92 +    }
    2.93 +
    2.94 +    
    2.95 +}
     3.1 --- a/emul/src/main/java/java/lang/Class.java	Wed Jan 16 12:25:50 2013 +0100
     3.2 +++ b/emul/src/main/java/java/lang/Class.java	Wed Jan 16 12:27:53 2013 +0100
     3.3 @@ -25,6 +25,7 @@
     3.4  
     3.5  package java.lang;
     3.6  
     3.7 +import java.io.ByteArrayInputStream;
     3.8  import org.apidesign.bck2brwsr.emul.AnnotationImpl;
     3.9  import java.io.InputStream;
    3.10  import java.lang.annotation.Annotation;
    3.11 @@ -144,7 +145,15 @@
    3.12       * @exception ClassNotFoundException if the class cannot be located
    3.13       */
    3.14      public static Class<?> forName(String className)
    3.15 -                throws ClassNotFoundException {
    3.16 +    throws ClassNotFoundException {
    3.17 +        if (className.startsWith("[")) {
    3.18 +            Class<?> arrType = defineArray(className);
    3.19 +            Class<?> c = arrType;
    3.20 +            while (c != null && c.isArray()) {
    3.21 +                c = c.getComponentType0(); // verify component type is sane
    3.22 +            }
    3.23 +            return arrType;
    3.24 +        }
    3.25          Class<?> c = loadCls(className, className.replace('.', '_'));
    3.26          if (c == null) {
    3.27              throw new ClassNotFoundException(className);
    3.28 @@ -215,7 +224,7 @@
    3.29          + "\nif (c['cons__V']) {"
    3.30          + "\n  if ((c.cons__V.access & 0x1) != 0) {"
    3.31          + "\n    var inst = c();"
    3.32 -        + "\n    c.cons__V(inst);"
    3.33 +        + "\n    c.cons__V.call(inst);"
    3.34          + "\n    return inst;"
    3.35          + "\n  }"
    3.36          + "\n  return illegal;"
    3.37 @@ -268,7 +277,15 @@
    3.38       *
    3.39       * @since JDK1.1
    3.40       */
    3.41 -    public native boolean isInstance(Object obj);
    3.42 +    public boolean isInstance(Object obj) {
    3.43 +        String prop = "$instOf_" + getName().replace('.', '_');
    3.44 +        return hasProperty(obj, prop);
    3.45 +    }
    3.46 +    
    3.47 +    @JavaScriptBody(args = { "who", "prop" }, body = 
    3.48 +        "if (who[prop]) return true; else return false;"
    3.49 +    )
    3.50 +    private static native boolean hasProperty(Object who, String prop);
    3.51  
    3.52  
    3.53      /**
    3.54 @@ -309,7 +326,7 @@
    3.55          return (getAccess() & 0x200) != 0;
    3.56      }
    3.57      
    3.58 -    @JavaScriptBody(args = "self", body = "return self.access;")
    3.59 +    @JavaScriptBody(args = {}, body = "return this.access;")
    3.60      private native int getAccess();
    3.61  
    3.62  
    3.63 @@ -321,7 +338,7 @@
    3.64       * @since   JDK1.1
    3.65       */
    3.66      public boolean isArray() {
    3.67 -        return false;
    3.68 +        return hasProperty(this, "array"); // NOI18N
    3.69      }
    3.70  
    3.71  
    3.72 @@ -353,8 +370,8 @@
    3.73       * @see     java.lang.Void#TYPE
    3.74       * @since JDK1.1
    3.75       */
    3.76 -    @JavaScriptBody(args = "self", body = 
    3.77 -           "if (self.primitive) return true;"
    3.78 +    @JavaScriptBody(args = {}, body = 
    3.79 +           "if (this.primitive) return true;"
    3.80          + "else return false;"
    3.81      )
    3.82      public native boolean isPrimitive();
    3.83 @@ -438,7 +455,7 @@
    3.84          return jvmName().replace('/', '.');
    3.85      }
    3.86  
    3.87 -    @JavaScriptBody(args = "self", body = "return self.jvmName;")
    3.88 +    @JavaScriptBody(args = {}, body = "return this.jvmName;")
    3.89      private native String jvmName();
    3.90  
    3.91      
    3.92 @@ -472,7 +489,7 @@
    3.93       *
    3.94       * @return the superclass of the class represented by this object.
    3.95       */
    3.96 -    @JavaScriptBody(args = "self", body = "return self.superclass;")
    3.97 +    @JavaScriptBody(args = {}, body = "return this.superclass;")
    3.98      public native Class<? super T> getSuperclass();
    3.99  
   3.100      /**
   3.101 @@ -881,13 +898,14 @@
   3.102       */
   3.103       public InputStream getResourceAsStream(String name) {
   3.104          name = resolveName(name);
   3.105 -        ClassLoader cl = getClassLoader0();
   3.106 -        if (cl==null) {
   3.107 -            // A system class.
   3.108 -            return ClassLoader.getSystemResourceAsStream(name);
   3.109 -        }
   3.110 -        return cl.getResourceAsStream(name);
   3.111 -    }
   3.112 +        byte[] arr = getResourceAsStream0(name);
   3.113 +        return arr == null ? null : new ByteArrayInputStream(arr);
   3.114 +     }
   3.115 +     
   3.116 +     @JavaScriptBody(args = "name", body = 
   3.117 +         "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
   3.118 +     )
   3.119 +     private static native byte[] getResourceAsStream0(String name);
   3.120  
   3.121      /**
   3.122       * Finds a resource with a given name.  The rules for searching resources
   3.123 @@ -925,7 +943,7 @@
   3.124       */
   3.125      public java.net.URL getResource(String name) {
   3.126          name = resolveName(name);
   3.127 -        ClassLoader cl = getClassLoader0();
   3.128 +        ClassLoader cl = null;
   3.129          if (cl==null) {
   3.130              // A system class.
   3.131              return ClassLoader.getSystemResource(name);
   3.132 @@ -989,9 +1007,6 @@
   3.133          throw new SecurityException();
   3.134      }
   3.135      
   3.136 -    // Package-private to allow ClassLoader access
   3.137 -    native ClassLoader getClassLoader0();    
   3.138 -
   3.139      /**
   3.140       * Returns the {@code Class} representing the component type of an
   3.141       * array.  If this class does not represent an array class this method
   3.142 @@ -1003,9 +1018,59 @@
   3.143       * @since JDK1.1
   3.144       */
   3.145      public Class<?> getComponentType() {
   3.146 +        if (isArray()) {
   3.147 +            try {
   3.148 +                return getComponentType0();
   3.149 +            } catch (ClassNotFoundException cnfe) {
   3.150 +                throw new IllegalStateException(cnfe);
   3.151 +            }
   3.152 +        }
   3.153          return null;
   3.154      }
   3.155  
   3.156 +    private Class<?> getComponentType0() throws ClassNotFoundException {
   3.157 +        String n = getName().substring(1);
   3.158 +        switch (n.charAt(0)) {
   3.159 +            case 'L': 
   3.160 +                n = n.substring(1, n.length() - 1);
   3.161 +                return Class.forName(n);
   3.162 +            case 'I':
   3.163 +                return Integer.TYPE;
   3.164 +            case 'J':
   3.165 +                return Long.TYPE;
   3.166 +            case 'D':
   3.167 +                return Double.TYPE;
   3.168 +            case 'F':
   3.169 +                return Float.TYPE;
   3.170 +            case 'B':
   3.171 +                return Byte.TYPE;
   3.172 +            case 'Z':
   3.173 +                return Boolean.TYPE;
   3.174 +            case 'S':
   3.175 +                return Short.TYPE;
   3.176 +            case 'V':
   3.177 +                return Void.TYPE;
   3.178 +            case 'C':
   3.179 +                return Character.TYPE;
   3.180 +            case '[':
   3.181 +                return defineArray(n);
   3.182 +            default:
   3.183 +                throw new ClassNotFoundException("Unknown component type of " + getName());
   3.184 +        }
   3.185 +    }
   3.186 +    
   3.187 +    @JavaScriptBody(args = { "sig" }, body = 
   3.188 +        "var c = Array[sig];\n" +
   3.189 +        "if (c) return c;\n" +
   3.190 +        "c = vm.java_lang_Class(true);\n" +
   3.191 +        "c.jvmName = sig;\n" +
   3.192 +        "c.superclass = vm.java_lang_Object(false).$class;\n" +
   3.193 +        "c.array = true;\n" +
   3.194 +        "Array[sig] = c;\n" +
   3.195 +        "return c;"
   3.196 +    )
   3.197 +    private static native Class<?> defineArray(String sig);
   3.198 +    
   3.199      /**
   3.200       * Returns true if and only if this class was declared as an enum in the
   3.201       * source code.
   3.202 @@ -1071,10 +1136,10 @@
   3.203              throw new ClassCastException(this.toString());
   3.204      }
   3.205  
   3.206 -    @JavaScriptBody(args = { "self", "ac" }, 
   3.207 +    @JavaScriptBody(args = { "ac" }, 
   3.208          body = 
   3.209 -          "if (self.anno) {"
   3.210 -        + "  return self.anno['L' + ac.jvmName + ';'];"
   3.211 +          "if (this.anno) {"
   3.212 +        + "  return this.anno['L' + ac.jvmName + ';'];"
   3.213          + "} else return null;"
   3.214      )
   3.215      private Object getAnnotationData(Class<?> annotationClass) {
   3.216 @@ -1093,8 +1158,8 @@
   3.217       * @throws NullPointerException {@inheritDoc}
   3.218       * @since 1.5
   3.219       */
   3.220 -    @JavaScriptBody(args = { "self", "ac" }, 
   3.221 -        body = "if (self.anno && self.anno['L' + ac.jvmName + ';']) { return true; }"
   3.222 +    @JavaScriptBody(args = { "ac" }, 
   3.223 +        body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
   3.224          + "else return false;"
   3.225      )
   3.226      public boolean isAnnotationPresent(
   3.227 @@ -1105,7 +1170,7 @@
   3.228          return getAnnotation(annotationClass) != null;
   3.229      }
   3.230  
   3.231 -    @JavaScriptBody(args = "self", body = "return self.anno;")
   3.232 +    @JavaScriptBody(args = {}, body = "return this.anno;")
   3.233      private Object getAnnotationData() {
   3.234          throw new UnsupportedOperationException();
   3.235      }
     4.1 --- a/emul/src/main/java/java/lang/Number.java	Wed Jan 16 12:25:50 2013 +0100
     4.2 +++ b/emul/src/main/java/java/lang/Number.java	Wed Jan 16 12:27:53 2013 +0100
     4.3 @@ -25,6 +25,8 @@
     4.4  
     4.5  package java.lang;
     4.6  
     4.7 +import org.apidesign.bck2brwsr.core.ExtraJavaScript;
     4.8 +
     4.9  /**
    4.10   * The abstract class <code>Number</code> is the superclass of classes
    4.11   * <code>BigDecimal</code>, <code>BigInteger</code>,
    4.12 @@ -46,6 +48,10 @@
    4.13   * @see     java.lang.Short
    4.14   * @since   JDK1.0
    4.15   */
    4.16 +@ExtraJavaScript(
    4.17 +    resource="/org/apidesign/vm4brwsr/emul/java_lang_Number.js",
    4.18 +    processByteCode=true
    4.19 +)
    4.20  public abstract class Number implements java.io.Serializable {
    4.21      /**
    4.22       * Returns the value of the specified number as an <code>int</code>.
     5.1 --- a/emul/src/main/java/java/lang/Object.java	Wed Jan 16 12:25:50 2013 +0100
     5.2 +++ b/emul/src/main/java/java/lang/Object.java	Wed Jan 16 12:27:53 2013 +0100
     5.3 @@ -66,7 +66,7 @@
     5.4       * @see    Class Literals, section 15.8.2 of
     5.5       *         <cite>The Java&trade; Language Specification</cite>.
     5.6       */
     5.7 -    @JavaScriptBody(args="self", body="return self.constructor.$class;")
     5.8 +    @JavaScriptBody(args={}, body="return this.constructor.$class;")
     5.9      public final native Class<?> getClass();
    5.10  
    5.11      /**
    5.12 @@ -104,13 +104,16 @@
    5.13       * @see     java.lang.Object#equals(java.lang.Object)
    5.14       * @see     java.lang.System#identityHashCode
    5.15       */
    5.16 -    @JavaScriptBody(args = "self", body = 
    5.17 -        "if (self.$hashCode) return self.$hashCode;\n"
    5.18 -        + "var h = Math.random() * Math.pow(2, 32);\n"
    5.19 -        + "return self.$hashCode = h & h;"
    5.20 +    @JavaScriptBody(args = {}, body = 
    5.21 +        "if (this.$hashCode) return this.$hashCode;\n"
    5.22 +        + "var h = this.computeHashCode__I();\n"
    5.23 +        + "return this.$hashCode = h & h;"
    5.24      )
    5.25      public native int hashCode();
    5.26  
    5.27 +    @JavaScriptBody(args = {}, body = "Math.random() * Math.pow(2, 32);")
    5.28 +    native int computeHashCode();
    5.29 +    
    5.30      /**
    5.31       * Indicates whether some other object is "equal to" this one.
    5.32       * <p>
     6.1 --- a/emul/src/main/java/java/lang/String.java	Wed Jan 16 12:25:50 2013 +0100
     6.2 +++ b/emul/src/main/java/java/lang/String.java	Wed Jan 16 12:27:53 2013 +0100
     6.3 @@ -108,10 +108,6 @@
     6.4  public final class String
     6.5      implements java.io.Serializable, Comparable<String>, CharSequence
     6.6  {
     6.7 -    @JavaScriptOnly
     6.8 -    /** Cache the hash code for the string */
     6.9 -    private int hash; // Default to 0
    6.10 -    
    6.11      /** real string to delegate to */
    6.12      private Object r;
    6.13  
    6.14 @@ -173,11 +169,11 @@
    6.15       * @param  value
    6.16       *         The initial value of the string
    6.17       */
    6.18 -    @JavaScriptBody(args = { "self", "charArr" }, body=
    6.19 +    @JavaScriptBody(args = { "charArr" }, body=
    6.20          "for (var i = 0; i < charArr.length; i++) {\n"
    6.21        + "  if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n"
    6.22        + "}\n"
    6.23 -      + "self.fld_r = charArr.join('');\n"
    6.24 +      + "this.fld_r = charArr.join('');\n"
    6.25      )
    6.26      public String(char value[]) {
    6.27      }
    6.28 @@ -203,12 +199,12 @@
    6.29       *          If the {@code offset} and {@code count} arguments index
    6.30       *          characters outside the bounds of the {@code value} array
    6.31       */
    6.32 -    @JavaScriptBody(args = { "self", "charArr", "off", "cnt" }, body =
    6.33 +    @JavaScriptBody(args = { "charArr", "off", "cnt" }, body =
    6.34          "var up = off + cnt;\n" +
    6.35          "for (var i = off; i < up; i++) {\n" +
    6.36          "  if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n" +
    6.37          "}\n" +
    6.38 -        "self.fld_r = charArr.slice(off, up).join(\"\");\n"
    6.39 +        "this.fld_r = charArr.slice(off, up).join(\"\");\n"
    6.40      )
    6.41      public String(char value[], int offset, int count) {
    6.42      }
    6.43 @@ -622,7 +618,7 @@
    6.44       * @return  the length of the sequence of characters represented by this
    6.45       *          object.
    6.46       */
    6.47 -    @JavaScriptBody(args = "self", body = "return self.toString().length;")
    6.48 +    @JavaScriptBody(args = {}, body = "return this.toString().length;")
    6.49      public int length() {
    6.50          throw new UnsupportedOperationException();
    6.51      }
    6.52 @@ -635,7 +631,7 @@
    6.53       *
    6.54       * @since 1.6
    6.55       */
    6.56 -    @JavaScriptBody(args = "self", body="return self.toString().length === 0;")
    6.57 +    @JavaScriptBody(args = {}, body="return this.toString().length === 0;")
    6.58      public boolean isEmpty() {
    6.59          return length() == 0;
    6.60      }
    6.61 @@ -658,8 +654,8 @@
    6.62       *             argument is negative or not less than the length of this
    6.63       *             string.
    6.64       */
    6.65 -    @JavaScriptBody(args = { "self", "index" }, 
    6.66 -        body = "return self.toString().charCodeAt(index);"
    6.67 +    @JavaScriptBody(args = { "index" }, 
    6.68 +        body = "return this.toString().charCodeAt(index);"
    6.69      )
    6.70      public char charAt(int index) {
    6.71          throw new UnsupportedOperationException();
    6.72 @@ -784,8 +780,8 @@
    6.73       * Copy characters from this string into dst starting at dstBegin.
    6.74       * This method doesn't perform any range checking.
    6.75       */
    6.76 -    @JavaScriptBody(args = { "self", "arr", "to" }, body = 
    6.77 -        "var s = self.toString();\n" +
    6.78 +    @JavaScriptBody(args = { "arr", "to" }, body = 
    6.79 +        "var s = this.toString();\n" +
    6.80          "for (var i = 0; i < s.length; i++) {\n" +
    6.81          "   arr[to++] = s[i];\n" +
    6.82          "}"
    6.83 @@ -824,8 +820,8 @@
    6.84       *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
    6.85       *                <code>dst.length</code></ul>
    6.86       */
    6.87 -    @JavaScriptBody(args = { "self", "beg", "end", "arr", "dst" }, body=
    6.88 -        "var s = self.toString();\n" +
    6.89 +    @JavaScriptBody(args = { "beg", "end", "arr", "dst" }, body=
    6.90 +        "var s = this.toString();\n" +
    6.91          "while (beg < end) {\n" +
    6.92          "  arr[dst++] = s[beg++];\n" +
    6.93          "}\n"
    6.94 @@ -997,9 +993,9 @@
    6.95       * @see  #compareTo(String)
    6.96       * @see  #equalsIgnoreCase(String)
    6.97       */
    6.98 -    @JavaScriptBody(args = { "self", "obj" }, body = 
    6.99 +    @JavaScriptBody(args = { "obj" }, body = 
   6.100          "return obj.$instOf_java_lang_String && "
   6.101 -        + "self.toString() === obj.toString();"
   6.102 +        + "this.toString() === obj.toString();"
   6.103      )
   6.104      public boolean equals(Object anObject) {
   6.105          if (this == anObject) {
   6.106 @@ -1424,9 +1420,9 @@
   6.107       *          this.substring(toffset).startsWith(prefix)
   6.108       *          </pre>
   6.109       */
   6.110 -    @JavaScriptBody(args = { "self", "find", "from" }, body=
   6.111 +    @JavaScriptBody(args = { "find", "from" }, body=
   6.112          "find = find.toString();\n" +
   6.113 -        "return self.toString().substring(from, from + find.length) === find;\n"
   6.114 +        "return this.toString().substring(from, from + find.length) === find;\n"
   6.115      )
   6.116      public boolean startsWith(String prefix, int toffset) {
   6.117          char ta[] = toCharArray();
   6.118 @@ -1491,26 +1487,18 @@
   6.119       *
   6.120       * @return  a hash code value for this object.
   6.121       */
   6.122 -    @JavaScriptBody(args = "self", body = 
   6.123 -        "var h = 0;\n" +
   6.124 -        "var s = self.toString();\n" +
   6.125 -        "for (var i = 0; i < s.length; i++) {\n" +
   6.126 -        "  var high = (h >> 16) & 0xffff, low = h & 0xffff;\n" +
   6.127 -        "  h = (((((31 * high) & 0xffff) << 16) >>> 0) + (31 * low) + s.charCodeAt(i)) & 0xffffffff;\n" +
   6.128 -        "}\n" +
   6.129 -        "return h;\n"
   6.130 -    )
   6.131      public int hashCode() {
   6.132 -        int h = hash;
   6.133 +        return super.hashCode();
   6.134 +    }
   6.135 +    int computeHashCode() {
   6.136 +        int h = 0;
   6.137          if (h == 0 && length() > 0) {
   6.138              int off = offset();
   6.139 -            char val[] = toCharArray();
   6.140              int len = length();
   6.141  
   6.142              for (int i = 0; i < len; i++) {
   6.143 -                h = 31*h + val[off++];
   6.144 +                h = 31*h + charAt(off++);
   6.145              }
   6.146 -            hash = h;
   6.147          }
   6.148          return h;
   6.149      }
   6.150 @@ -1582,9 +1570,9 @@
   6.151       *          than or equal to <code>fromIndex</code>, or <code>-1</code>
   6.152       *          if the character does not occur.
   6.153       */
   6.154 -    @JavaScriptBody(args = { "self", "ch", "from" }, body = 
   6.155 +    @JavaScriptBody(args = { "ch", "from" }, body = 
   6.156          "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
   6.157 -        "return self.toString().indexOf(ch, from);\n"
   6.158 +        "return this.toString().indexOf(ch, from);\n"
   6.159      )
   6.160      public int indexOf(int ch, int fromIndex) {
   6.161          if (fromIndex < 0) {
   6.162 @@ -1691,9 +1679,9 @@
   6.163       *          than or equal to <code>fromIndex</code>, or <code>-1</code>
   6.164       *          if the character does not occur before that point.
   6.165       */
   6.166 -    @JavaScriptBody(args = { "self", "ch", "from" }, body = 
   6.167 +    @JavaScriptBody(args = { "ch", "from" }, body = 
   6.168          "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
   6.169 -        "return self.toString().lastIndexOf(ch, from);"
   6.170 +        "return this.toString().lastIndexOf(ch, from);"
   6.171      )
   6.172      public int lastIndexOf(int ch, int fromIndex) {
   6.173          if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
   6.174 @@ -1766,8 +1754,8 @@
   6.175       *          starting at the specified index,
   6.176       *          or {@code -1} if there is no such occurrence.
   6.177       */
   6.178 -    @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
   6.179 -        "return self.toString().indexOf(str.toString(), fromIndex);"
   6.180 +    @JavaScriptBody(args = { "str", "fromIndex" }, body =
   6.181 +        "return this.toString().indexOf(str.toString(), fromIndex);"
   6.182      )
   6.183      public native int indexOf(String str, int fromIndex);
   6.184  
   6.185 @@ -1806,8 +1794,8 @@
   6.186       *          searching backward from the specified index,
   6.187       *          or {@code -1} if there is no such occurrence.
   6.188       */
   6.189 -    @JavaScriptBody(args = { "self", "s", "from" }, body = 
   6.190 -        "return self.toString().lastIndexOf(s.toString(), from);"
   6.191 +    @JavaScriptBody(args = { "s", "from" }, body = 
   6.192 +        "return this.toString().lastIndexOf(s.toString(), from);"
   6.193      )
   6.194      public int lastIndexOf(String str, int fromIndex) {
   6.195          return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
   6.196 @@ -1915,8 +1903,8 @@
   6.197       *             <code>beginIndex</code> is larger than
   6.198       *             <code>endIndex</code>.
   6.199       */
   6.200 -    @JavaScriptBody(args = { "self", "beginIndex", "endIndex" }, body = 
   6.201 -        "return self.toString().substring(beginIndex, endIndex);"
   6.202 +    @JavaScriptBody(args = { "beginIndex", "endIndex" }, body = 
   6.203 +        "return this.toString().substring(beginIndex, endIndex);"
   6.204      )
   6.205      public String substring(int beginIndex, int endIndex) {
   6.206          if (beginIndex < 0) {
   6.207 @@ -2024,10 +2012,10 @@
   6.208       * @return  a string derived from this string by replacing every
   6.209       *          occurrence of <code>oldChar</code> with <code>newChar</code>.
   6.210       */
   6.211 -    @JavaScriptBody(args = { "self", "arg1", "arg2" }, body =
   6.212 +    @JavaScriptBody(args = { "arg1", "arg2" }, body =
   6.213          "if (typeof arg1 === 'number') arg1 = String.fromCharCode(arg1);\n" +
   6.214          "if (typeof arg2 === 'number') arg2 = String.fromCharCode(arg2);\n" +
   6.215 -        "var s = self.toString();\n" +
   6.216 +        "var s = this.toString();\n" +
   6.217          "for (;;) {\n" +
   6.218          "  var ret = s.replace(arg1, arg2);\n" +
   6.219          "  if (ret === s) {\n" +
   6.220 @@ -2090,8 +2078,8 @@
   6.221       * @since 1.4
   6.222       * @spec JSR-51
   6.223       */
   6.224 -    @JavaScriptBody(args = { "self", "regex" }, body = 
   6.225 -          "self = self.toString();\n"
   6.226 +    @JavaScriptBody(args = { "regex" }, body = 
   6.227 +          "var self = this.toString();\n"
   6.228          + "var re = new RegExp(regex.toString());\n"
   6.229          + "var r = re.exec(self);\n"
   6.230          + "return r != null && r.length > 0 && self.length == r[0].length;"
   6.231 @@ -2508,7 +2496,7 @@
   6.232       * @return  the <code>String</code>, converted to lowercase.
   6.233       * @see     java.lang.String#toLowerCase(Locale)
   6.234       */
   6.235 -    @JavaScriptBody(args = "self", body = "return self.toLowerCase();")
   6.236 +    @JavaScriptBody(args = {}, body = "return this.toLowerCase();")
   6.237      public String toLowerCase() {
   6.238          throw new UnsupportedOperationException("Should be supported but without connection to locale");
   6.239      }
   6.240 @@ -2674,7 +2662,7 @@
   6.241       * @return  the <code>String</code>, converted to uppercase.
   6.242       * @see     java.lang.String#toUpperCase(Locale)
   6.243       */
   6.244 -    @JavaScriptBody(args = "self", body = "return self.toUpperCase();")
   6.245 +    @JavaScriptBody(args = {}, body = "return this.toUpperCase();")
   6.246      public String toUpperCase() {
   6.247          throw new UnsupportedOperationException();
   6.248      }
   6.249 @@ -2730,7 +2718,7 @@
   6.250       *
   6.251       * @return  the string itself.
   6.252       */
   6.253 -    @JavaScriptBody(args = "self", body = "return self.toString();")
   6.254 +    @JavaScriptBody(args = {}, body = "return this.toString();")
   6.255      public String toString() {
   6.256          return this;
   6.257      }
   6.258 @@ -2742,7 +2730,6 @@
   6.259       *          of this string and whose contents are initialized to contain
   6.260       *          the character sequence represented by this string.
   6.261       */
   6.262 -    @JavaScriptBody(args = "self", body = "return self.toString().split('');")
   6.263      public char[] toCharArray() {
   6.264          char result[] = new char[length()];
   6.265          getChars(0, length(), result, 0);
     7.1 --- a/emul/src/main/java/java/lang/Throwable.java	Wed Jan 16 12:25:50 2013 +0100
     7.2 +++ b/emul/src/main/java/java/lang/Throwable.java	Wed Jan 16 12:27:53 2013 +0100
     7.3 @@ -783,7 +783,7 @@
     7.4          return this;
     7.5      }
     7.6  
     7.7 -    @JavaScriptBody(args = { "self", "dummy" }, body = "")
     7.8 +    @JavaScriptBody(args = { "dummy" }, body = "")
     7.9      private native Throwable fillInStackTrace(int dummy);
    7.10  
    7.11      /**
     8.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Wed Jan 16 12:25:50 2013 +0100
     8.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Wed Jan 16 12:27:53 2013 +0100
     8.3 @@ -559,6 +559,9 @@
     8.4          if (type == Short.TYPE) {
     8.5              return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
     8.6          }
     8.7 +        if (type == Character.TYPE) {
     8.8 +            return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o);
     8.9 +        }
    8.10          if (type.getName().equals("void")) {
    8.11              return null;
    8.12          }
    8.13 @@ -592,6 +595,9 @@
    8.14          if (type == Short.TYPE) {
    8.15              return toRaw("shortValue__S", o);
    8.16          }
    8.17 +        if (type == Character.TYPE) {
    8.18 +            return toRaw("charValue__C", o);
    8.19 +        }
    8.20          if (type.getName().equals("void")) {
    8.21              return o;
    8.22          }
    8.23 @@ -640,10 +646,10 @@
    8.24          return Modifier.isSynthetic(getModifiers());
    8.25      }
    8.26  
    8.27 -    @JavaScriptBody(args = { "self", "ac" }, 
    8.28 +    @JavaScriptBody(args = { "ac" }, 
    8.29          body = 
    8.30 -          "if (self.fld_data.anno) {"
    8.31 -        + "  return self.fld_data.anno['L' + ac.jvmName + ';'];"
    8.32 +          "if (this.fld_data.anno) {"
    8.33 +        + "  return this.fld_data.anno['L' + ac.jvmName + ';'];"
    8.34          + "} else return null;"
    8.35      )
    8.36      private Object getAnnotationData(Class<?> annotationClass) {
     9.1 --- a/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java	Wed Jan 16 12:25:50 2013 +0100
     9.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java	Wed Jan 16 12:27:53 2013 +0100
     9.3 @@ -144,6 +144,8 @@
     9.4                          return Short.TYPE;
     9.5                      case 'V':
     9.6                          return Void.TYPE;
     9.7 +                    case 'C':
     9.8 +                        return Character.TYPE;
     9.9                      case 'L':
    9.10                          try {
    9.11                              int up = sig.indexOf("_2");
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_Number.js	Wed Jan 16 12:27:53 2013 +0100
    10.3 @@ -0,0 +1,9 @@
    10.4 +// empty line needed here
    10.5 +Number.prototype.add32 = function(x) { return (this + x) | 0; };
    10.6 +Number.prototype.sub32 = function(x) { return (this - x) | 0; };
    10.7 +Number.prototype.mul32 = function(x) { 
    10.8 +    return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
    10.9 +};
   10.10 +
   10.11 +Number.prototype.toInt8 = function()  { return (this << 24) >> 24; };
   10.12 +Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
   10.13 \ No newline at end of file
    11.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Wed Jan 16 12:25:50 2013 +0100
    11.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Wed Jan 16 12:27:53 2013 +0100
    11.3 @@ -2,10 +2,25 @@
    11.4  vm.java_lang_String(false);
    11.5  
    11.6  // we need initialized arrays
    11.7 -Array.prototype.fillNulls = function() {
    11.8 -  for(var i = 0; i < this.length; i++) this[i] = null;
    11.9 +Array.prototype.initWith = function(sig, value) {
   11.10 +  for(var i = 0; i < this.length; i++) this[i] = value;
   11.11 +  this.jvmName = sig;
   11.12    return this;
   11.13  };
   11.14 +Array.prototype.at = function(indx, value) {
   11.15 +  if (indx < 0 || indx > this.length) {
   11.16 +      var e = vm.java_lang_ArrayIndexOutOfBoundsException(true);
   11.17 +      e.constructor.cons__VLjava_lang_String_2.call(e, indx.toString());
   11.18 +      throw e;
   11.19 +  }
   11.20 +  if (arguments.length === 2) {
   11.21 +      this[indx] = value;
   11.22 +  }
   11.23 +  return this[indx];
   11.24 +};
   11.25 +Array.prototype.getClass__Ljava_lang_Class_2 = function() {
   11.26 +  return vm.java_lang_Class(false).defineArray__Ljava_lang_Class_2Ljava_lang_String_2(this.jvmName);
   11.27 +};
   11.28  Array.prototype.clone__Ljava_lang_Object_2 = function() {
   11.29    var s = this.length;
   11.30    var ret = new Array(s);
    12.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java	Wed Jan 16 12:25:50 2013 +0100
    12.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java	Wed Jan 16 12:27:53 2013 +0100
    12.3 @@ -37,8 +37,8 @@
    12.4      void add(Object objectType) {
    12.5          addElement(objectType);
    12.6      }
    12.7 -    @JavaScriptBody(args = { "self", "obj" }, body = 
    12.8 -        "self.push(obj);"
    12.9 +    @JavaScriptBody(args = { "obj" }, body = 
   12.10 +        "this.push(obj);"
   12.11      )
   12.12      void addElement(Object obj) {
   12.13          final int s = size();
   12.14 @@ -46,16 +46,16 @@
   12.15          setElementAt(obj, s);
   12.16      }
   12.17  
   12.18 -    @JavaScriptBody(args = { "self" }, body = 
   12.19 -        "return self.length;"
   12.20 +    @JavaScriptBody(args = { }, body = 
   12.21 +        "return this.length;"
   12.22      )
   12.23      int size() {
   12.24          return arr == null ? 0 : arr.length;
   12.25      }
   12.26  
   12.27 -    @JavaScriptBody(args = { "self", "newArr" }, body =
   12.28 -        "for (var i = 0; i < self.length; i++) {\n"
   12.29 -      + "  newArr[i] = self[i];\n"
   12.30 +    @JavaScriptBody(args = { "newArr" }, body =
   12.31 +        "for (var i = 0; i < this.length; i++) {\n"
   12.32 +      + "  newArr[i] = this[i];\n"
   12.33        + "}\n")
   12.34      void copyInto(Object[] newArr) {
   12.35          if (arr == null) {
   12.36 @@ -67,8 +67,8 @@
   12.37          }
   12.38      }
   12.39  
   12.40 -    @JavaScriptBody(args = { "self", "index" }, body =
   12.41 -        "return self[index];"
   12.42 +    @JavaScriptBody(args = { "index" }, body =
   12.43 +        "return this[index];"
   12.44      )
   12.45      Object elementAt(int index) {
   12.46          return arr[index];
   12.47 @@ -80,8 +80,8 @@
   12.48          arr = newArr;
   12.49      }
   12.50  
   12.51 -    @JavaScriptBody(args = { "self", "val", "index" }, body = 
   12.52 -        "self[index] = val;"
   12.53 +    @JavaScriptBody(args = { "val", "index" }, body = 
   12.54 +        "this[index] = val;"
   12.55      )
   12.56      void setElementAt(Object val, int index) {
   12.57          arr[index] = val;
    13.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Wed Jan 16 12:25:50 2013 +0100
    13.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Wed Jan 16 12:27:53 2013 +0100
    13.3 @@ -43,7 +43,7 @@
    13.4  import javax.tools.Diagnostic;
    13.5  import javax.tools.FileObject;
    13.6  import javax.tools.StandardLocation;
    13.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    13.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    13.9  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   13.10  import org.openide.util.lookup.ServiceProvider;
   13.11  
   13.12 @@ -55,7 +55,7 @@
   13.13  @ServiceProvider(service=Processor.class)
   13.14  @SupportedAnnotationTypes({
   13.15      "org.apidesign.bck2brwsr.htmlpage.api.Page",
   13.16 -    "org.apidesign.bck2brwsr.htmlpage.api.OnClick"
   13.17 +    "org.apidesign.bck2brwsr.htmlpage.api.On"
   13.18  })
   13.19  public final class PageProcessor extends AbstractProcessor {
   13.20      @Override
   13.21 @@ -149,11 +149,11 @@
   13.22              }
   13.23              TypeElement type = (TypeElement)clazz;
   13.24              for (Element method : clazz.getEnclosedElements()) {
   13.25 -                OnClick oc = method.getAnnotation(OnClick.class);
   13.26 +                On oc = method.getAnnotation(On.class);
   13.27                  if (oc != null) {
   13.28                      for (String id : oc.id()) {
   13.29                          if (pp.tagNameForId(id) == null) {
   13.30 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
   13.31 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + id + " does not exist in the HTML page. Found only " + pp.ids(), method);
   13.32                              return false;
   13.33                          }
   13.34                          ExecutableElement ee = (ExecutableElement)method;
   13.35 @@ -162,21 +162,21 @@
   13.36                              hasParam = false;
   13.37                          } else {
   13.38                              if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
   13.39 -                                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
   13.40 +                                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method should either have no arguments or one String argument", ee);
   13.41                                  return false;
   13.42                              }
   13.43                              hasParam = true;
   13.44                          }
   13.45                          if (!ee.getModifiers().contains(Modifier.STATIC)) {
   13.46 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
   13.47 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method has to be static", ee);
   13.48                              return false;
   13.49                          }
   13.50                          if (ee.getModifiers().contains(Modifier.PRIVATE)) {
   13.51 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
   13.52 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method can't be private", ee);
   13.53                              return false;
   13.54                          }
   13.55 -                        w.append("  ").append(cnstnt(id)).
   13.56 -                            append(".addOnClick(new Runnable() { public void run() {\n");
   13.57 +                        w.append("  OnEvent." + oc.event()).append(".of(").append(cnstnt(id)).
   13.58 +                            append(").perform(new Runnable() { public void run() {\n");
   13.59                          w.append("    ").append(type.getSimpleName().toString()).
   13.60                              append('.').append(ee.getSimpleName()).append("(");
   13.61                          if (hasParam) {
    14.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Wed Jan 16 12:25:50 2013 +0100
    14.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Wed Jan 16 12:27:53 2013 +0100
    14.3 @@ -37,29 +37,45 @@
    14.4          body="var e = window.document.getElementById(el.fld_id);\n"
    14.5             + "e[property] = value;\n"
    14.6      )
    14.7 -    static void setAttribute(Element el, String property, Object value) {
    14.8 -        throw new UnsupportedOperationException("Needs JavaScript!");
    14.9 -    }
   14.10 +    static native void setAttribute(Element el, String property, Object value);
   14.11  
   14.12      @JavaScriptBody(
   14.13          args={"el", "property"},
   14.14          body="var e = window.document.getElementById(el.fld_id);\n"
   14.15             + "return e[property];\n"
   14.16      )
   14.17 -    static Object getAttribute(Element el, String property) {
   14.18 -        throw new UnsupportedOperationException("Needs JavaScript!");
   14.19 -    }
   14.20 +    static native Object getAttribute(Element el, String property);
   14.21      
   14.22      /** Executes given runnable when user performs a "click" on the given
   14.23       * element.
   14.24       * @param r the runnable to execute, never null
   14.25       */
   14.26      @JavaScriptBody(
   14.27 -        args={"el", "r"},
   14.28 -        body="var e = window.document.getElementById(el.fld_id);\n"
   14.29 -           + "e.onclick = function() { r.run__V(); };\n"
   14.30 +        args={ "ev", "r" },
   14.31 +        body="var e = window.document.getElementById(this.fld_id);\n"
   14.32 +           + "e[ev.fld_id] = function() { r.run__V(); };\n"
   14.33      )
   14.34 -    public final void addOnClick(Runnable r) {
   14.35 -        throw new UnsupportedOperationException("Needs JavaScript!");
   14.36 +    final native void on(OnEvent ev, Runnable r);
   14.37 +
   14.38 +    /** Shows alert message dialog in a browser.
   14.39 +     * @param msg the message to show
   14.40 +     */
   14.41 +    @JavaScriptBody(args = "msg", body = "alert(msg);")
   14.42 +    public static native void alert(String msg);
   14.43 +
   14.44 +    /** Generic way to query any attribute of this element.
   14.45 +     * @param property name of the attribute
   14.46 +     */
   14.47 +    public final Object getAttribute(String property) {
   14.48 +        return getAttribute(this, property);
   14.49 +    }
   14.50 +    
   14.51 +    /** Generic way to change an attribute of this element.
   14.52 +     * 
   14.53 +     * @param property name of the attribute
   14.54 +     * @param value value to associate with the attribute
   14.55 +     */
   14.56 +    public final void setAttribute(String property, Object value) {
   14.57 +        setAttribute(this, property, value);
   14.58      }
   14.59  }
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/On.java	Wed Jan 16 12:27:53 2013 +0100
    15.3 @@ -0,0 +1,35 @@
    15.4 +/**
    15.5 + * Back 2 Browser Bytecode Translator
    15.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    15.7 + *
    15.8 + * This program is free software: you can redistribute it and/or modify
    15.9 + * it under the terms of the GNU General Public License as published by
   15.10 + * the Free Software Foundation, version 2 of the License.
   15.11 + *
   15.12 + * This program is distributed in the hope that it will be useful,
   15.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.15 + * GNU General Public License for more details.
   15.16 + *
   15.17 + * You should have received a copy of the GNU General Public License
   15.18 + * along with this program. Look for COPYING file in the top folder.
   15.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   15.20 + */
   15.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   15.22 +
   15.23 +import java.lang.annotation.ElementType;
   15.24 +import java.lang.annotation.Retention;
   15.25 +import java.lang.annotation.RetentionPolicy;
   15.26 +import java.lang.annotation.Target;
   15.27 +
   15.28 +/** Adds an onClick handler to an element identified by given <em>id</em>.
   15.29 + * Apply on a <code>public static void</code> method with no arguments.
   15.30 + *
   15.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   15.32 + */
   15.33 +@Retention(RetentionPolicy.SOURCE)
   15.34 +@Target(ElementType.METHOD)
   15.35 +public @interface On {
   15.36 +    OnEvent event();
   15.37 +    String[] id();
   15.38 +}
    16.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java	Wed Jan 16 12:25:50 2013 +0100
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,34 +0,0 @@
    16.4 -/**
    16.5 - * Back 2 Browser Bytecode Translator
    16.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    16.7 - *
    16.8 - * This program is free software: you can redistribute it and/or modify
    16.9 - * it under the terms of the GNU General Public License as published by
   16.10 - * the Free Software Foundation, version 2 of the License.
   16.11 - *
   16.12 - * This program is distributed in the hope that it will be useful,
   16.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 - * GNU General Public License for more details.
   16.16 - *
   16.17 - * You should have received a copy of the GNU General Public License
   16.18 - * along with this program. Look for COPYING file in the top folder.
   16.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   16.20 - */
   16.21 -package org.apidesign.bck2brwsr.htmlpage.api;
   16.22 -
   16.23 -import java.lang.annotation.ElementType;
   16.24 -import java.lang.annotation.Retention;
   16.25 -import java.lang.annotation.RetentionPolicy;
   16.26 -import java.lang.annotation.Target;
   16.27 -
   16.28 -/** Adds an onClick handler to an element identified by given <em>id</em>.
   16.29 - * Apply on a <code>public static void</code> method with no arguments.
   16.30 - *
   16.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   16.32 - */
   16.33 -@Retention(RetentionPolicy.SOURCE)
   16.34 -@Target(ElementType.METHOD)
   16.35 -public @interface OnClick {
   16.36 -    String[] id();
   16.37 -}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnController.java	Wed Jan 16 12:27:53 2013 +0100
    17.3 @@ -0,0 +1,43 @@
    17.4 +/**
    17.5 + * Back 2 Browser Bytecode Translator
    17.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    17.7 + *
    17.8 + * This program is free software: you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU General Public License as published by
   17.10 + * the Free Software Foundation, version 2 of the License.
   17.11 + *
   17.12 + * This program is distributed in the hope that it will be useful,
   17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 + * GNU General Public License for more details.
   17.16 + *
   17.17 + * You should have received a copy of the GNU General Public License
   17.18 + * along with this program. Look for COPYING file in the top folder.
   17.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   17.20 + */
   17.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   17.22 +
   17.23 +/** Controller created via {@link OnEvent#of(org.apidesign.bck2brwsr.htmlpage.api.Element[])}.
   17.24 + *
   17.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   17.26 + */
   17.27 +public final class OnController {
   17.28 +    private final Element[] arr;
   17.29 +    private final OnEvent event;
   17.30 +    
   17.31 +    OnController(OnEvent event, Element[] arr) {
   17.32 +        this.event = event;
   17.33 +        this.arr = arr;
   17.34 +    }
   17.35 +    
   17.36 +    /** Registers a runnable to be performed on associated {@link OnEvent} 
   17.37 +     * and {@link Element}.
   17.38 +     * 
   17.39 +     * @see OnEvent#of
   17.40 +     */
   17.41 +    public void perform(Runnable r) {
   17.42 +        for (Element e : arr) {
   17.43 +            e.on(event, r);
   17.44 +        }
   17.45 +    }
   17.46 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnEvent.java	Wed Jan 16 12:27:53 2013 +0100
    18.3 @@ -0,0 +1,95 @@
    18.4 +/**
    18.5 + * Back 2 Browser Bytecode Translator
    18.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18.7 + *
    18.8 + * This program is free software: you can redistribute it and/or modify
    18.9 + * it under the terms of the GNU General Public License as published by
   18.10 + * the Free Software Foundation, version 2 of the License.
   18.11 + *
   18.12 + * This program is distributed in the hope that it will be useful,
   18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.15 + * GNU General Public License for more details.
   18.16 + *
   18.17 + * You should have received a copy of the GNU General Public License
   18.18 + * along with this program. Look for COPYING file in the top folder.
   18.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   18.20 + */
   18.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   18.22 +
   18.23 +/** Type of events to use in connection with {@link On} annotation.
   18.24 + *
   18.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   18.26 + */
   18.27 +public enum OnEvent {
   18.28 +    ABORT("onabort"),
   18.29 +    BLUR("onblur"),
   18.30 +    CAN_PLAY("oncanplay"),
   18.31 +    CAN_PLAY_THROUGH("oncanplaythrough"),
   18.32 +    CLICK("onclick"),
   18.33 +    CONTEXT_MENU("oncontextmenu"),
   18.34 +    DBL_CLICK("ondblclick"),
   18.35 +    DRAG("ondrag"),
   18.36 +    DRAG_END("ondragend"),
   18.37 +    DRAG_ENTER("ondragenter"),
   18.38 +    DRAG_LEAVE("ondragleave"),
   18.39 +    DRAG_OVER("ondragover"),
   18.40 +    DRAG_START("ondragstart"),
   18.41 +    DROP("ondrop"),
   18.42 +    DURATION_CHANGE("ondurationchange"),
   18.43 +    EMPTIED("onemptied"),
   18.44 +    ENDED("onended"),
   18.45 +    ERROR("onerror"),
   18.46 +    FOCUS("onfocus"),
   18.47 +    FORM_CHANGE("onformchange"),
   18.48 +    FORM_INPUT("onforminput"),
   18.49 +    INPUT("oninput"),
   18.50 +    INVALID("oninvalid"),
   18.51 +    KEY_DOWN("onkeydown"),
   18.52 +    KEY_PRESS("onkeypress"),
   18.53 +    KEY_UP("onkeyup"),
   18.54 +    LOAD("onload"),
   18.55 +    LOADED_DATA("onloadeddata"),
   18.56 +    LOADED_META_DATA("onloadedmetadata"),
   18.57 +    LOAD_START("onloadstart"),
   18.58 +    MOUSE_DOWN("onmousedown"),
   18.59 +    MOUSE_MOVE("onmousemove"),
   18.60 +    MOUSE_OUT("onmouseout"),
   18.61 +    MOUSE_OVER("onmouseover"),
   18.62 +    MOUSE_UP("onmouseup"),
   18.63 +    MOUSE_WHEEL("onmousewheel"),
   18.64 +    PAUSE("onpause"),
   18.65 +    PLAY("onplay"),
   18.66 +    PLAYING("onplaying"),
   18.67 +    PROGRESS("onprogress"),
   18.68 +    RATE_CHANGE("onratechange"),
   18.69 +    READY_STATE_CHANGE("onreadystatechange"),
   18.70 +    SCROLL("onscroll"),
   18.71 +    SEEKED("onseeked"),
   18.72 +    SEEKING("onseeking"),
   18.73 +    SELECT("onselect"),
   18.74 +    SHOW("onshow"),
   18.75 +    STALLED("onstalled"),
   18.76 +    SUBMIT("onsubmit"),
   18.77 +    SUSPEND("onsuspend"),
   18.78 +    TIME_UPDATE("ontimeupdate"),
   18.79 +    VOLUME_CHANGE("onvolumechange"),
   18.80 +    WAITING("onwaiting");
   18.81 +    
   18.82 +    final String id;
   18.83 +    
   18.84 +    private OnEvent(String id) {
   18.85 +        this.id = id;
   18.86 +    }
   18.87 +    
   18.88 +    /** What should happen when this even happen on one
   18.89 +     * of associated elements. Continue by calling {@link OnController#perform(java.lang.Runnable)}
   18.90 +     * method.
   18.91 +     * 
   18.92 +     * @param elmnts one or more elements
   18.93 +     * @return controller with <code>perform</code> method.
   18.94 +     */
   18.95 +    public OnController of(Element... elmnts) {
   18.96 +        return new OnController(this, elmnts);
   18.97 +    }
   18.98 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Timer.java	Wed Jan 16 12:27:53 2013 +0100
    19.3 @@ -0,0 +1,59 @@
    19.4 +/**
    19.5 + * Back 2 Browser Bytecode Translator
    19.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    19.7 + *
    19.8 + * This program is free software: you can redistribute it and/or modify
    19.9 + * it under the terms of the GNU General Public License as published by
   19.10 + * the Free Software Foundation, version 2 of the License.
   19.11 + *
   19.12 + * This program is distributed in the hope that it will be useful,
   19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.15 + * GNU General Public License for more details.
   19.16 + *
   19.17 + * You should have received a copy of the GNU General Public License
   19.18 + * along with this program. Look for COPYING file in the top folder.
   19.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   19.20 + */
   19.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   19.22 +
   19.23 +import java.io.Closeable;
   19.24 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   19.25 +
   19.26 +/**
   19.27 + *
   19.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   19.29 + */
   19.30 +public class Timer implements Closeable {
   19.31 +    private final Object t;
   19.32 +    
   19.33 +    private Timer(Object t) {
   19.34 +        this.t = t;
   19.35 +    }
   19.36 +    
   19.37 +    /** Creates a timer that invokes provided runnable on a fixed interval
   19.38 +     * 
   19.39 +     * @param r the runnable to execute
   19.40 +     * @param time milliseconds to invoke the timer periodically
   19.41 +     */
   19.42 +    public static Timer create(Runnable r, int time) {
   19.43 +        return new Timer(interval(r, time));
   19.44 +    }
   19.45 +    
   19.46 +    @JavaScriptBody(args = { "r", "time" }, body = 
   19.47 +        "return window.setInterval(function() { r.run__V(); }, time);"
   19.48 +    )
   19.49 +    private static native Object interval(Runnable r, int time);
   19.50 +
   19.51 +    @JavaScriptBody(args = { "self" }, body = 
   19.52 +        "window.clearInterval(self);"
   19.53 +    )
   19.54 +    private static native void close(Object self);
   19.55 +    
   19.56 +    /** Cancels this timer.
   19.57 +     */
   19.58 +    @Override
   19.59 +    public void close() {
   19.60 +        close(t);
   19.61 +    }
   19.62 +}
    20.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java	Wed Jan 16 12:25:50 2013 +0100
    20.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java	Wed Jan 16 12:27:53 2013 +0100
    20.3 @@ -17,7 +17,8 @@
    20.4   */
    20.5  package org.apidesign.bck2brwsr.htmlpage;
    20.6  
    20.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    20.8 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
    20.9 +import org.apidesign.bck2brwsr.htmlpage.api.On;
   20.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   20.11  
   20.12  /** Trivial demo for the bck2brwsr project. First of all start
   20.13 @@ -42,12 +43,12 @@
   20.14   */
   20.15  @Page(xhtml="TestPage.html")
   20.16  public class PageController {
   20.17 -    @OnClick(id="pg.button")
   20.18 +    @On(event = CLICK, id="pg.button")
   20.19      static void updateTitle() {
   20.20          TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
   20.21      }
   20.22      
   20.23 -    @OnClick(id={ "pg.title", "pg.text" })
   20.24 +    @On(event = CLICK, id={ "pg.title", "pg.text" })
   20.25      static void click(String id) {
   20.26          if (!id.equals("pg.title")) {
   20.27              throw new IllegalStateException();
    21.1 --- a/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Jan 16 12:25:50 2013 +0100
    21.2 +++ b/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Jan 16 12:27:53 2013 +0100
    21.3 @@ -17,7 +17,8 @@
    21.4   */
    21.5  package org.apidesign.bck2brwsr.mavenhtml;
    21.6  
    21.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    21.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    21.9 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
   21.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   21.11  
   21.12  /** HTML5 & Java demo showing the power of 
   21.13 @@ -31,21 +32,21 @@
   21.14      private static double memory;
   21.15      private static String operation;
   21.16      
   21.17 -    @OnClick(id="clear")
   21.18 +    @On(event = CLICK, id="clear")
   21.19      static void clear() {
   21.20          memory = 0;
   21.21          operation = null;
   21.22          Calculator.DISPLAY.setValue("0");
   21.23      }
   21.24      
   21.25 -    @OnClick(id= { "plus", "minus", "mul", "div" })
   21.26 +    @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
   21.27      static void applyOp(String op) {
   21.28          memory = getValue();
   21.29          operation = op;
   21.30          Calculator.DISPLAY.setValue("0");
   21.31      }
   21.32      
   21.33 -    @OnClick(id="result")
   21.34 +    @On(event = CLICK, id="result")
   21.35      static void computeTheValue() {
   21.36          switch (operation) {
   21.37              case "plus": setValue(memory + getValue()); break;
   21.38 @@ -56,7 +57,7 @@
   21.39          }
   21.40      }
   21.41      
   21.42 -    @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   21.43 +    @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   21.44      static void addDigit(String digit) {
   21.45          digit = digit.substring(1);
   21.46          String v = Calculator.DISPLAY.getValue();
    22.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Jan 16 12:25:50 2013 +0100
    22.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Jan 16 12:27:53 2013 +0100
    22.3 @@ -17,7 +17,8 @@
    22.4   */
    22.5  package org.apidesign.bck2brwsr.mavenhtml;
    22.6  
    22.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    22.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    22.9 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
   22.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   22.11  
   22.12  /** HTML5 & Java demo showing the power of 
   22.13 @@ -31,21 +32,21 @@
   22.14      private static double memory;
   22.15      private static String operation;
   22.16      
   22.17 -    @OnClick(id="clear")
   22.18 +    @On(event = CLICK, id="clear")
   22.19      static void clear() {
   22.20          memory = 0;
   22.21          operation = null;
   22.22          Calculator.DISPLAY.setValue("0");
   22.23      }
   22.24      
   22.25 -    @OnClick(id= { "plus", "minus", "mul", "div" })
   22.26 +    @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
   22.27      static void applyOp(String op) {
   22.28          memory = getValue();
   22.29          operation = op;
   22.30          Calculator.DISPLAY.setValue("0");
   22.31      }
   22.32      
   22.33 -    @OnClick(id="result")
   22.34 +    @On(event = CLICK, id="result")
   22.35      static void computeTheValue() {
   22.36          switch (operation) {
   22.37              case "plus": setValue(memory + getValue()); break;
   22.38 @@ -56,7 +57,7 @@
   22.39          }
   22.40      }
   22.41      
   22.42 -    @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   22.43 +    @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   22.44      static void addDigit(String digit) {
   22.45          digit = digit.substring(1);
   22.46          String v = Calculator.DISPLAY.getValue();
    23.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Wed Jan 16 12:25:50 2013 +0100
    23.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Wed Jan 16 12:27:53 2013 +0100
    23.3 @@ -247,20 +247,14 @@
    23.4          
    23.5          URI uri = new URI("http://localhost:" + port + page);
    23.6          LOG.log(Level.INFO, "Showing {0}", uri);
    23.7 -//        try {
    23.8 -//            Desktop.getDesktop().browse(uri);
    23.9 -//            return null;
   23.10 -//        } catch (UnsupportedOperationException ex)
   23.11 -        {
   23.12 -//            File dir = File.createTempFile("chrome", ".dir");
   23.13 -//            dir.delete();
   23.14 -//            dir.mkdirs();
   23.15 -//            String[] cmd = { 
   23.16 -//                "google-chrome", "--user-data-dir=" + dir, "--app=" + uri.toString()
   23.17 -//            };
   23.18 -//            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
   23.19 -//            final Process process = Runtime.getRuntime().exec(cmd);
   23.20 -//            return new Object[] { process, dir };
   23.21 +        if (cmd == null) {
   23.22 +            try {
   23.23 +                java.awt.Desktop.getDesktop().browse(uri);
   23.24 +                LOG.log(Level.INFO, "Desktop.browse successfully finished");
   23.25 +                return null;
   23.26 +            } catch (UnsupportedOperationException ex) {
   23.27 +                LOG.log(Level.INFO, "Desktop.browse not supported", ex);
   23.28 +            }
   23.29          }
   23.30          {
   23.31              String cmdName = cmd == null ? "xdg-open" : cmd;
   23.32 @@ -375,8 +369,13 @@
   23.33                      r = r.substring(1);
   23.34                  }
   23.35              }
   23.36 -            if (r.endsWith(".html") || r.endsWith(".xhtml")) {
   23.37 +            if (r.endsWith(".html")) {
   23.38                  response.setContentType("text/html");
   23.39 +                LOG.info("Content type text/html");
   23.40 +            }
   23.41 +            if (r.endsWith(".xhtml")) {
   23.42 +                response.setContentType("application/xhtml+xml");
   23.43 +                LOG.info("Content type application/xhtml+xml");
   23.44              }
   23.45              OutputStream os = response.getOutputStream();
   23.46              try (InputStream is = res.get(r)) {
    24.1 --- a/mojo/pom.xml	Wed Jan 16 12:25:50 2013 +0100
    24.2 +++ b/mojo/pom.xml	Wed Jan 16 12:27:53 2013 +0100
    24.3 @@ -11,7 +11,7 @@
    24.4    <artifactId>mojo</artifactId>
    24.5    <version>0.3-SNAPSHOT</version>
    24.6    <packaging>maven-plugin</packaging>
    24.7 -  <name>Maven Mojo to Compile to JavaScript</name>
    24.8 +  <name>Bck2Brwsr Maven Project</name>
    24.9    <url>http://maven.apache.org</url>
   24.10        <build>
   24.11          <plugins>
    25.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Wed Jan 16 12:25:50 2013 +0100
    25.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Wed Jan 16 12:27:53 2013 +0100
    25.3 @@ -44,7 +44,7 @@
    25.4      /** Resource to show as initial page */
    25.5      @Parameter
    25.6      private String startpage;
    25.7 -    
    25.8 +
    25.9      @Parameter(defaultValue="${project}")
   25.10      private MavenProject prj;
   25.11      
   25.12 @@ -63,9 +63,9 @@
   25.13              
   25.14              Closeable httpServer;
   25.15              try {
   25.16 -                httpServer = Launcher.showURL(url, startpage);
   25.17 +                httpServer = Launcher.showURL(url, startpage());
   25.18              } catch (Exception ex) {
   25.19 -                throw new MojoExecutionException("Can't open " + startpage, ex);
   25.20 +                throw new MojoExecutionException("Can't open " + startpage(), ex);
   25.21              }
   25.22              System.in.read();
   25.23              httpServer.close();
   25.24 @@ -73,35 +73,9 @@
   25.25              throw new MojoExecutionException("Can't show the browser", ex);
   25.26          }
   25.27      }
   25.28 -
   25.29 -    private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
   25.30 -        if (!dir.isDirectory()) {
   25.31 -            throw new MojoExecutionException("Not a directory " + dir);
   25.32 -        }
   25.33 -        File[] arr = dir.listFiles();
   25.34 -        if (arr.length == 1 && arr[0].isDirectory()) {
   25.35 -            return findNonEmptyFolder(arr[0]);
   25.36 -        }
   25.37 -        return dir;
   25.38 -    }
   25.39 -
   25.40 -    private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
   25.41 -        File[] files = toCheck.listFiles();
   25.42 -        if (files != null) {
   25.43 -            long newest = 0L;
   25.44 -            for (File f : files) {
   25.45 -                long lastModified = collectAllClasses(prefix + f.getName() + "/", f, arr);
   25.46 -                if (newest < lastModified) {
   25.47 -                    newest = lastModified;
   25.48 -                }
   25.49 -            }
   25.50 -            return newest;
   25.51 -        } else if (toCheck.getName().endsWith(".class")) {
   25.52 -            arr.add(prefix.substring(0, prefix.length() - 7));
   25.53 -            return toCheck.lastModified();
   25.54 -        } else {
   25.55 -            return 0L;
   25.56 -        }
   25.57 +    
   25.58 +    private String startpage() {
   25.59 +        return startpage;
   25.60      }
   25.61  
   25.62      private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/mojo/src/main/resources/META-INF/maven/archetype-metadata.xml	Wed Jan 16 12:27:53 2013 +0100
    26.3 @@ -0,0 +1,42 @@
    26.4 +<?xml version="1.0" encoding="UTF-8"?>
    26.5 +<!--
    26.6 +
    26.7 +    Back 2 Browser Bytecode Translator
    26.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    26.9 +
   26.10 +    This program is free software: you can redistribute it and/or modify
   26.11 +    it under the terms of the GNU General Public License as published by
   26.12 +    the Free Software Foundation, version 2 of the License.
   26.13 +
   26.14 +    This program is distributed in the hope that it will be useful,
   26.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.17 +    GNU General Public License for more details.
   26.18 +
   26.19 +    You should have received a copy of the GNU General Public License
   26.20 +    along with this program. Look for COPYING file in the top folder.
   26.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   26.22 +
   26.23 +-->
   26.24 +<archetype-descriptor name="bck2brwsr">
   26.25 +  <fileSets>
   26.26 +    <fileSet filtered="true" packaged="true">
   26.27 +      <directory>src/main/java</directory>
   26.28 +      <includes>
   26.29 +        <include>**/*.java</include>
   26.30 +      </includes>
   26.31 +    </fileSet>
   26.32 +    <fileSet filtered="true" packaged="true">
   26.33 +      <directory>src/main/resources</directory>
   26.34 +      <includes>
   26.35 +        <include>**/*.xhtml</include>
   26.36 +      </includes>
   26.37 +    </fileSet>
   26.38 +    <fileSet filtered="false" packaged="false">
   26.39 +      <directory></directory>
   26.40 +      <includes>
   26.41 +        <include>nbactions.xml</include>
   26.42 +      </includes>
   26.43 +    </fileSet>
   26.44 +  </fileSets>    
   26.45 +</archetype-descriptor>
   26.46 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/mojo/src/main/resources/archetype-resources/nbactions.xml	Wed Jan 16 12:27:53 2013 +0100
    27.3 @@ -0,0 +1,10 @@
    27.4 +<?xml version="1.0" encoding="UTF-8"?>
    27.5 +<actions>
    27.6 +    <action>
    27.7 +        <actionName>run</actionName>
    27.8 +        <goals>
    27.9 +            <goal>process-classes</goal>
   27.10 +            <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
   27.11 +        </goals>
   27.12 +    </action>
   27.13 +</actions>
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml	Wed Jan 16 12:27:53 2013 +0100
    28.3 @@ -0,0 +1,57 @@
    28.4 +<?xml version="1.0"?>
    28.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    28.6 +  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    28.7 +  <modelVersion>4.0.0</modelVersion>
    28.8 +
    28.9 +  <groupId>${groupId}</groupId>
   28.10 +  <artifactId>${artifactId}</artifactId>
   28.11 +  <version>${version}</version>
   28.12 +  <packaging>jar</packaging>
   28.13 +
   28.14 +  <name>${artifactId}</name>
   28.15 +
   28.16 +  <properties>
   28.17 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   28.18 +  </properties>
   28.19 +  <build>
   28.20 +      <plugins>
   28.21 +            <plugin>
   28.22 +                <groupId>org.apidesign.bck2brwsr</groupId>
   28.23 +                <artifactId>mojo</artifactId>
   28.24 +                <version>0.3-SNAPSHOT</version>
   28.25 +                <executions>
   28.26 +                    <execution>
   28.27 +                        <goals>
   28.28 +                            <goal>brwsr</goal>
   28.29 +                        </goals>
   28.30 +                    </execution>
   28.31 +                </executions>
   28.32 +                <configuration>
   28.33 +                    <startpage>${package.replace('.','/')}/index.xhtml</startpage>
   28.34 +                </configuration>
   28.35 +            </plugin>
   28.36 +         <plugin>
   28.37 +            <groupId>org.apache.maven.plugins</groupId>
   28.38 +            <artifactId>maven-compiler-plugin</artifactId>
   28.39 +            <version>2.3.2</version>
   28.40 +            <configuration>
   28.41 +               <source>1.7</source>
   28.42 +               <target>1.7</target>
   28.43 +            </configuration>
   28.44 +         </plugin>
   28.45 +      </plugins>
   28.46 +  </build>
   28.47 +
   28.48 +  <dependencies>
   28.49 +    <dependency>
   28.50 +      <groupId>org.apidesign.bck2brwsr</groupId>
   28.51 +      <artifactId>emul</artifactId>
   28.52 +      <version>0.3-SNAPSHOT</version>
   28.53 +    </dependency>
   28.54 +    <dependency>
   28.55 +      <groupId>org.apidesign.bck2brwsr</groupId>
   28.56 +      <artifactId>javaquery.api</artifactId>
   28.57 +      <version>0.3-SNAPSHOT</version>
   28.58 +    </dependency>
   28.59 +  </dependencies>
   28.60 +</project>
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/java/App.java	Wed Jan 16 12:27:53 2013 +0100
    29.3 @@ -0,0 +1,17 @@
    29.4 +package ${package};
    29.5 +
    29.6 +import org.apidesign.bck2brwsr.htmlpage.api.*;
    29.7 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
    29.8 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
    29.9 +
   29.10 +/** Edit the index.xhtml file. Use 'id' to name certain HTML elements.
   29.11 + * Use this class to define behavior of the elements.
   29.12 + */
   29.13 +@Page(xhtml="index.xhtml", className="Index")
   29.14 +public class App {
   29.15 +    @On(event = CLICK, id="hello")
   29.16 +    static void hello() {
   29.17 +        Index.HELLO.setDisabled(true);
   29.18 +        Element.alert("Hello World!");
   29.19 +    }
   29.20 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/resources/index.xhtml	Wed Jan 16 12:27:53 2013 +0100
    30.3 @@ -0,0 +1,16 @@
    30.4 +<?xml version="1.0" encoding="UTF-8"?>
    30.5 +<!DOCTYPE html>
    30.6 +<html xmlns="http://www.w3.org/1999/xhtml">
    30.7 +    <head>
    30.8 +        <title>Bck2Brwsr's Hello World</title>
    30.9 +    </head>
   30.10 +    <body>
   30.11 +        <button id="hello">Hello World!</button>
   30.12 +
   30.13 +        <script src="/bck2brwsr.js"></script>
   30.14 +        <script src="/vm.js"></script>
   30.15 +        <script type="text/javascript">
   30.16 +            vm.loadClass('${package}.Index');
   30.17 +        </script>
   30.18 +    </body>
   30.19 +</html>
    31.1 --- a/pom.xml	Wed Jan 16 12:25:50 2013 +0100
    31.2 +++ b/pom.xml	Wed Jan 16 12:27:53 2013 +0100
    31.3 @@ -73,6 +73,8 @@
    31.4                         <exclude>javap/**</exclude>
    31.5                         <exclude>*</exclude>
    31.6                         <exclude>.*/**</exclude>
    31.7 +                       <exclude>mojo/src/main/resources/archetype-resources/**</exclude>
    31.8 +                       <exclude>vmtest/src/test/resources/**</exclude>
    31.9                    </excludes>
   31.10                </configuration>
   31.11            </plugin>
   31.12 @@ -110,4 +112,4 @@
   31.13    <properties>
   31.14        <license>COPYING</license>
   31.15    </properties>
   31.16 -</project>
   31.17 \ No newline at end of file
   31.18 +</project>
    32.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Wed Jan 16 12:25:50 2013 +0100
    32.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Wed Jan 16 12:27:53 2013 +0100
    32.3 @@ -37,7 +37,7 @@
    32.4   *   return null; // byte[] for the resource
    32.5   * });
    32.6   * </pre>
    32.7 - * In this scenario, when a request for a unknown class is made, the loader
    32.8 + * In this scenario, when a request for an unknown class is made, the loader
    32.9   * function is asked for its byte code and the system dynamically transforms
   32.10   * it to JavaScript.
   32.11   *
    33.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Jan 16 12:25:50 2013 +0100
    33.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Jan 16 12:27:53 2013 +0100
    33.3 @@ -19,6 +19,7 @@
    33.4  
    33.5  import java.io.IOException;
    33.6  import java.io.InputStream;
    33.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    33.8  import org.apidesign.javap.AnnotationParser;
    33.9  import org.apidesign.javap.ClassData;
   33.10  import org.apidesign.javap.FieldData;
   33.11 @@ -249,13 +250,14 @@
   33.12                  new LocalsMapper(stackMapIterator.getArguments());
   33.13  
   33.14          out.append(prefix).append(name).append(" = function(");
   33.15 -        lmapper.outputArguments(out);
   33.16 +        lmapper.outputArguments(out, m.isStatic());
   33.17          out.append(") {").append("\n");
   33.18  
   33.19          final byte[] byteCodes = m.getCode();
   33.20          if (byteCodes == null) {
   33.21              out.append("  throw 'no code found for ")
   33.22 -               .append(m.getInternalSig()).append("';\n");
   33.23 +               .append(jc.getClassName()).append('.')
   33.24 +               .append(m.getName()).append("';\n");
   33.25              out.append("};");
   33.26              return;
   33.27          }
   33.28 @@ -274,6 +276,9 @@
   33.29                  out.append(';');
   33.30              }
   33.31          }
   33.32 +        if (!m.isStatic()) {
   33.33 +            out.append("  var ").append(" lcA0 = this;\n");
   33.34 +        }
   33.35  
   33.36          // maxStack includes two stack positions for every pushed long / double
   33.37          // so this might generate more stack variables than we need
   33.38 @@ -490,7 +495,7 @@
   33.39                      emit(out, "@1 = @2;", lmapper.setD(3), smapper.popD());
   33.40                      break;
   33.41                  case opc_iadd:
   33.42 -                    emit(out, "@1 += @2;", smapper.getI(1), smapper.popI());
   33.43 +                    emit(out, "@1 = @1.add32(@2);", smapper.getI(1), smapper.popI());
   33.44                      break;
   33.45                  case opc_ladd:
   33.46                      emit(out, "@1 += @2;", smapper.getL(1), smapper.popL());
   33.47 @@ -502,7 +507,7 @@
   33.48                      emit(out, "@1 += @2;", smapper.getD(1), smapper.popD());
   33.49                      break;
   33.50                  case opc_isub:
   33.51 -                    emit(out, "@1 -= @2;", smapper.getI(1), smapper.popI());
   33.52 +                    emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI());
   33.53                      break;
   33.54                  case opc_lsub:
   33.55                      emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
   33.56 @@ -514,7 +519,7 @@
   33.57                      emit(out, "@1 -= @2;", smapper.getD(1), smapper.popD());
   33.58                      break;
   33.59                  case opc_imul:
   33.60 -                    emit(out, "@1 *= @2;", smapper.getI(1), smapper.popI());
   33.61 +                    emit(out, "@1 = @1.mul32(@2);", smapper.getI(1), smapper.popI());
   33.62                      break;
   33.63                  case opc_lmul:
   33.64                      emit(out, "@1 *= @2;", smapper.getL(1), smapper.popL());
   33.65 @@ -671,9 +676,13 @@
   33.66                           smapper.popD(), smapper.pushL());
   33.67                      break;
   33.68                  case opc_i2b:
   33.69 +                    emit(out, "@1 = @1.toInt8();", smapper.getI(0));
   33.70 +                    break;
   33.71                  case opc_i2c:
   33.72 +                    out.append("{ /* number conversion */ }");
   33.73 +                    break;
   33.74                  case opc_i2s:
   33.75 -                    out.append("{ /* number conversion */ }");
   33.76 +                    emit(out, "@1 = @1.toInt16();", smapper.getI(0));
   33.77                      break;
   33.78                  case opc_aconst_null:
   33.79                      emit(out, "@1 = null;", smapper.pushA());
   33.80 @@ -904,28 +913,53 @@
   33.81                      break;
   33.82                  }
   33.83                  case opc_newarray:
   33.84 -                    ++i; // skip type of array
   33.85 -                    emit(out, "@2 = new Array(@1).fillNulls();",
   33.86 -                         smapper.popI(), smapper.pushA());
   33.87 +                    int atype = readByte(byteCodes, ++i);
   33.88 +                    String jvmType;
   33.89 +                    switch (atype) {
   33.90 +                        case 4: jvmType = "[Z"; break;
   33.91 +                        case 5: jvmType = "[C"; break;
   33.92 +                        case 6: jvmType = "[F"; break;
   33.93 +                        case 7: jvmType = "[D"; break;
   33.94 +                        case 8: jvmType = "[B"; break;
   33.95 +                        case 9: jvmType = "[S"; break;
   33.96 +                        case 10: jvmType = "[I"; break;
   33.97 +                        case 11: jvmType = "[J"; break;
   33.98 +                        default: throw new IllegalStateException("Array type: " + atype);
   33.99 +                    }
  33.100 +                    emit(out, "@2 = new Array(@1).initWith('@3', 0);",
  33.101 +                         smapper.popI(), smapper.pushA(), jvmType);
  33.102                      break;
  33.103 -                case opc_anewarray:
  33.104 -                    i += 2; // skip type of array
  33.105 -                    emit(out, "@2 = new Array(@1).fillNulls();",
  33.106 -                         smapper.popI(), smapper.pushA());
  33.107 +                case opc_anewarray: {
  33.108 +                    int type = readIntArg(byteCodes, i);
  33.109 +                    i += 2;
  33.110 +                    String typeName = jc.getClassName(type);
  33.111 +                    if (typeName.startsWith("[")) {
  33.112 +                        typeName = "[" + typeName;
  33.113 +                    } else {
  33.114 +                        typeName = "[L" + typeName + ";";
  33.115 +                    }
  33.116 +                    emit(out, "@2 = new Array(@1).initWith('@3', null);",
  33.117 +                         smapper.popI(), smapper.pushA(), typeName);
  33.118                      break;
  33.119 +                }
  33.120                  case opc_multianewarray: {
  33.121 +                    int type = readIntArg(byteCodes, i);
  33.122                      i += 2;
  33.123 +                    String typeName = jc.getClassName(type);
  33.124                      int dim = readByte(byteCodes, ++i);
  33.125                      out.append("{ var a0 = new Array(").append(smapper.popI())
  33.126 -                       .append(").fillNulls();");
  33.127 +                       .append(").initWith('").append(typeName).append("', null);");
  33.128                      for (int d = 1; d < dim; d++) {
  33.129 +                        typeName = typeName.substring(1);
  33.130                          out.append("\n  var l" + d).append(" = ")
  33.131                             .append(smapper.popI()).append(';');
  33.132                          out.append("\n  for (var i" + d).append (" = 0; i" + d).
  33.133                              append(" < a" + (d - 1)).
  33.134                              append(".length; i" + d).append("++) {");
  33.135                          out.append("\n    var a" + d).
  33.136 -                            append (" = new Array(l" + d).append(").fillNulls();");
  33.137 +                            append (" = new Array(l" + d).append(").initWith('")
  33.138 +                            .append(typeName).append("', ")
  33.139 +                            .append(typeName.length() == 2 ? "0" : "null").append(");");
  33.140                          out.append("\n    a" + (d - 1)).append("[i" + d).append("] = a" + d).
  33.141                              append(";");
  33.142                      }
  33.143 @@ -939,49 +973,49 @@
  33.144                      emit(out, "@2 = @1.length;", smapper.popA(), smapper.pushI());
  33.145                      break;
  33.146                  case opc_lastore:
  33.147 -                    emit(out, "@3[@2] = @1;",
  33.148 +                    emit(out, "@3.at(@2, @1);",
  33.149                           smapper.popL(), smapper.popI(), smapper.popA());
  33.150                      break;
  33.151                  case opc_fastore:
  33.152 -                    emit(out, "@3[@2] = @1;",
  33.153 +                    emit(out, "@3.at(@2, @1);",
  33.154                           smapper.popF(), smapper.popI(), smapper.popA());
  33.155                      break;
  33.156                  case opc_dastore:
  33.157 -                    emit(out, "@3[@2] = @1;",
  33.158 +                    emit(out, "@3.at(@2, @1);",
  33.159                           smapper.popD(), smapper.popI(), smapper.popA());
  33.160                      break;
  33.161                  case opc_aastore:
  33.162 -                    emit(out, "@3[@2] = @1;",
  33.163 +                    emit(out, "@3.at(@2, @1);",
  33.164                           smapper.popA(), smapper.popI(), smapper.popA());
  33.165                      break;
  33.166                  case opc_iastore:
  33.167                  case opc_bastore:
  33.168                  case opc_castore:
  33.169                  case opc_sastore:
  33.170 -                    emit(out, "@3[@2] = @1;",
  33.171 +                    emit(out, "@3.at(@2, @1);",
  33.172                           smapper.popI(), smapper.popI(), smapper.popA());
  33.173                      break;
  33.174                  case opc_laload:
  33.175 -                    emit(out, "@3 = @2[@1];",
  33.176 +                    emit(out, "@3 = @2.at(@1);",
  33.177                           smapper.popI(), smapper.popA(), smapper.pushL());
  33.178                      break;
  33.179                  case opc_faload:
  33.180 -                    emit(out, "@3 = @2[@1];",
  33.181 +                    emit(out, "@3 = @2.at(@1);",
  33.182                           smapper.popI(), smapper.popA(), smapper.pushF());
  33.183                      break;
  33.184                  case opc_daload:
  33.185 -                    emit(out, "@3 = @2[@1];",
  33.186 +                    emit(out, "@3 = @2.at(@1);",
  33.187                           smapper.popI(), smapper.popA(), smapper.pushD());
  33.188                      break;
  33.189                  case opc_aaload:
  33.190 -                    emit(out, "@3 = @2[@1];",
  33.191 +                    emit(out, "@3 = @2.at(@1);",
  33.192                           smapper.popI(), smapper.popA(), smapper.pushA());
  33.193                      break;
  33.194                  case opc_iaload:
  33.195                  case opc_baload:
  33.196                  case opc_caload:
  33.197                  case opc_saload:
  33.198 -                    emit(out, "@3 = @2[@1];",
  33.199 +                    emit(out, "@3 = @2.at(@1);",
  33.200                           smapper.popI(), smapper.popA(), smapper.pushI());
  33.201                      break;
  33.202                  case opc_pop:
  33.203 @@ -1329,7 +1363,11 @@
  33.204              out.append("constructor.");
  33.205          }
  33.206          out.append(mn);
  33.207 -        out.append('(');
  33.208 +        if (isStatic) {
  33.209 +            out.append('(');
  33.210 +        } else {
  33.211 +            out.append(".call(");
  33.212 +        }
  33.213          if (numArguments > 0) {
  33.214              out.append(vars[0]);
  33.215              for (int j = 1; j < numArguments; ++j) {
  33.216 @@ -1365,10 +1403,11 @@
  33.217          out.append(vars[0]).append('.');
  33.218          out.append(mn);
  33.219          out.append('(');
  33.220 -        out.append(vars[0]);
  33.221 +        String sep = "";
  33.222          for (int j = 1; j < numArguments; ++j) {
  33.223 -            out.append(", ");
  33.224 +            out.append(sep);
  33.225              out.append(vars[j]);
  33.226 +            sep = ", ";
  33.227          }
  33.228          out.append(");");
  33.229          i += 2;
  33.230 @@ -1442,15 +1481,8 @@
  33.231          final String mn = findMethodName(m, cnt);
  33.232          out.append(prefix).append(mn);
  33.233          out.append(" = function(");
  33.234 -        String space;
  33.235 -        int index;
  33.236 -        if (!isStatic) {                
  33.237 -            space = outputArg(out, p.args, 0);
  33.238 -            index = 1;
  33.239 -        } else {
  33.240 -            space = "";
  33.241 -            index = 0;
  33.242 -        }
  33.243 +        String space = "";
  33.244 +        int index = 0;
  33.245          for (int i = 0; i < cnt.length(); i++) {
  33.246              out.append(space);
  33.247              space = outputArg(out, p.args, index);
  33.248 @@ -1594,9 +1626,19 @@
  33.249              if (e.catch_cpx != 0) { //not finally
  33.250                  final String classInternalName = jc.getClassName(e.catch_cpx);
  33.251                  addReference(classInternalName);
  33.252 -                out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  33.253 -                out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
  33.254 -                out.append("}\n");
  33.255 +                if ("java/lang/Throwable".equals(classInternalName)) {
  33.256 +                    out.append("if (e.$instOf_java_lang_Throwable) {");
  33.257 +                    out.append("  stA0 = e;");
  33.258 +                    out.append("} else {");
  33.259 +                    out.append("  stA0 = vm.java_lang_Throwable(true);");
  33.260 +                    out.append("  vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());");
  33.261 +                    out.append("}");
  33.262 +                    out.append("gt=" + e.handler_pc + "; continue;");
  33.263 +                } else {
  33.264 +                    out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  33.265 +                    out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
  33.266 +                    out.append("}\n");
  33.267 +                }
  33.268              } else {
  33.269                  finallyPC = e.handler_pc;
  33.270              }
    34.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java	Wed Jan 16 12:25:50 2013 +0100
    34.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java	Wed Jan 16 12:27:53 2013 +0100
    34.3 @@ -33,13 +33,14 @@
    34.4          localTypeRecords = new TypeArray(initTypeRecords);
    34.5      }
    34.6  
    34.7 -    public void outputArguments(final Appendable out) throws IOException {
    34.8 +    public void outputArguments(final Appendable out, boolean isStatic) throws IOException {
    34.9          final int argRecordCount = argTypeRecords.getSize();
   34.10 -        if (argRecordCount > 0) {
   34.11 -            Variable variable = getVariable(argTypeRecords, 0);
   34.12 +        int first = isStatic ? 0 : 1;
   34.13 +        if (argRecordCount > first) {
   34.14 +            Variable variable = getVariable(argTypeRecords, first);
   34.15              out.append(variable);
   34.16  
   34.17 -            int i = variable.isCategory2() ? 2 : 1;
   34.18 +            int i = first + (variable.isCategory2() ? 2 : 1);
   34.19              while (i < argRecordCount) {
   34.20                  variable = getVariable(argTypeRecords, i);
   34.21                  out.append(", ");
    35.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed Jan 16 12:25:50 2013 +0100
    35.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed Jan 16 12:27:53 2013 +0100
    35.3 @@ -117,14 +117,20 @@
    35.4              + "    var loader = {};\n"
    35.5              + "    loader.vm = vm;\n"
    35.6              + "    loader.loadClass = function(name) {\n"
    35.7 -            + "      var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
    35.8 +            + "      var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
    35.9              + "      var fn = vm[attr];\n"
   35.10              + "      if (fn) return fn(false);\n"
   35.11              + "      if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
   35.12              + "      return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
   35.13              + "        load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
   35.14              + "    }\n"
   35.15 -            + "    if (args[0]) vm.loadClass = loader.loadClass;\n"
   35.16 +            + "    if (args[0]) {\n"
   35.17 +            + "      vm.loadClass = loader.loadClass;\n"
   35.18 +            + "      vm.loadBytes = function(name) {\n"
   35.19 +            + "        if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
   35.20 +            + "        return args[0](name);\n"
   35.21 +            + "      }\n"
   35.22 +            + "    }\n"
   35.23              + "    return loader;\n"
   35.24              + "  };\n");
   35.25          out.append("}(this));");
    36.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Wed Jan 16 12:25:50 2013 +0100
    36.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Wed Jan 16 12:27:53 2013 +0100
    36.3 @@ -112,17 +112,17 @@
    36.4              this.lazy = vm;
    36.5          }
    36.6          
    36.7 -        @JavaScriptBody(args = {"self", "n"},
    36.8 +        @JavaScriptBody(args = {"n"},
    36.9          body =
   36.10 -        "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();"
   36.11 -        + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();"
   36.12 -        + "\nvar lazy = self.fld_lazy;"
   36.13 +        "var cls = n.replace__Ljava_lang_String_2CC('/','_').toString();"
   36.14 +        + "\nvar dot = n.replace__Ljava_lang_String_2CC('/','.').toString();"
   36.15 +        + "\nvar lazy = this.fld_lazy;"
   36.16          + "\nvar loader = lazy.fld_loader;"
   36.17          + "\nvar vm = loader.vm;"
   36.18          + "\nif (vm[cls]) return false;"
   36.19          + "\nvm[cls] = function() {"
   36.20          + "\n  var instance = arguments.length == 0 || arguments[0] === true;"
   36.21 -        + "\n  return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(lazy, dot, instance);"
   36.22 +        + "\n  return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(dot, instance);"
   36.23          + "\n};"
   36.24          + "\nreturn true;")
   36.25          @Override
    37.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Wed Jan 16 12:25:50 2013 +0100
    37.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Wed Jan 16 12:27:53 2013 +0100
    37.3 @@ -51,6 +51,16 @@
    37.4          return doubles[4][0];
    37.5      }
    37.6      
    37.7 +    static double[][] dbls = new double[1][2];
    37.8 +    public static double twoDoubles() {
    37.9 +        return dbls[0][0] + dbls[0][0];
   37.10 +    }
   37.11 +
   37.12 +    static int[][] tints = new int[1][2];
   37.13 +    public static int twoInts() {
   37.14 +        return tints[0][0] + tints[0][0];
   37.15 +    }
   37.16 +    
   37.17      private static final Array[] ARR = { new Array(), new Array(), new Array() };
   37.18      
   37.19      private static Array[][] arr() {
   37.20 @@ -98,6 +108,11 @@
   37.21          return sum;
   37.22      }
   37.23      
   37.24 +    public static int sum(int size) {
   37.25 +        int[] arr = new int[size];
   37.26 +        return arr[0] + arr[1];
   37.27 +    }
   37.28 +    
   37.29      static void arraycopy(char[] value, int srcBegin, char[] dst, int dstBegin, int count) {
   37.30          while (count-- > 0) {
   37.31              dst[dstBegin++] = value[srcBegin++];
    38.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Wed Jan 16 12:25:50 2013 +0100
    38.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Wed Jan 16 12:27:53 2013 +0100
    38.3 @@ -27,6 +27,11 @@
    38.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
    38.5   */
    38.6  public class ArrayTest {
    38.7 +    @Test public void intArrayShouldBeFilledWithZeroes() throws Exception {
    38.8 +            assertExec("0 + 0", Array.class, "sum__II", 
    38.9 +            Double.valueOf(0), 2
   38.10 +        );
   38.11 +    }
   38.12      @Test public void verifySimpleIntOperation() throws Exception {
   38.13              assertExec("CheckTheSum", Array.class, "simple__IZ", 
   38.14              Double.valueOf(15), false
   38.15 @@ -48,6 +53,17 @@
   38.16              Double.valueOf(105)
   38.17          );
   38.18      }
   38.19 +
   38.20 +    @Test public void twoDoubles() throws Exception {
   38.21 +        assertExec("Elements are initialized", Array.class, "twoDoubles__D", 
   38.22 +            Double.valueOf(0)
   38.23 +        );
   38.24 +    }
   38.25 +    @Test public void twoInts() throws Exception {
   38.26 +        assertExec("Elements are initialized", Array.class, "twoInts__I", 
   38.27 +            Double.valueOf(0)
   38.28 +        );
   38.29 +    }
   38.30      
   38.31      @Test public void doesCopyArrayWork() throws Exception {
   38.32          assertExec("Returns 'a'", Array.class, "copyArray__C", Double.valueOf('a'));
    39.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Wed Jan 16 12:25:50 2013 +0100
    39.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Wed Jan 16 12:27:53 2013 +0100
    39.3 @@ -17,6 +17,8 @@
    39.4   */
    39.5  package org.apidesign.vm4brwsr;
    39.6  
    39.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    39.8 +
    39.9  /**
   39.10   *
   39.11   * @author tom
   39.12 @@ -47,6 +49,18 @@
   39.13          //join point
   39.14          return res;
   39.15      }
   39.16 +    
   39.17 +    @JavaScriptBody(args = "msg", body = "throw msg;")
   39.18 +    public static void thrw(String msg) {}
   39.19 +    
   39.20 +    public static String catchThrowableCatchesAll() {
   39.21 +        try {
   39.22 +            thrw("Hello!");
   39.23 +            return "Not here!";
   39.24 +        } catch (Throwable ex) {
   39.25 +            return ex.getMessage();
   39.26 +        }
   39.27 +    }
   39.28  
   39.29      public static String newInstance(String n) {
   39.30          try {
    40.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Wed Jan 16 12:25:50 2013 +0100
    40.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Wed Jan 16 12:27:53 2013 +0100
    40.3 @@ -38,6 +38,16 @@
    40.4      }
    40.5  
    40.6      @Test
    40.7 +    public void catchJavaScriptStringAsThrowable() throws Exception {
    40.8 +        assertExec(
    40.9 +            "Throw hello!",
   40.10 +            Exceptions.class,
   40.11 +            "catchThrowableCatchesAll__Ljava_lang_String_2",
   40.12 +            "Hello!"
   40.13 +        );
   40.14 +    }
   40.15 +
   40.16 +    @Test
   40.17      public void verifyMethodWithTryCatchThrow() throws Exception {
   40.18              assertExec(
   40.19                      "Throw",
    41.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Wed Jan 16 12:25:50 2013 +0100
    41.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Wed Jan 16 12:27:53 2013 +0100
    41.3 @@ -125,4 +125,11 @@
    41.4      public static boolean iofObject() {
    41.5          return jsObj() instanceof Object;
    41.6      }
    41.7 +    
    41.8 +    public static int jscall() {
    41.9 +        return jsgetbytes(new Instance());
   41.10 +    }
   41.11 +    
   41.12 +    @JavaScriptBody(args = { "instance" }, body = "return instance.getByte__B();")
   41.13 +    private static native int jsgetbytes(Instance instance);
   41.14  }
    42.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Wed Jan 16 12:25:50 2013 +0100
    42.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Wed Jan 16 12:27:53 2013 +0100
    42.3 @@ -131,6 +131,14 @@
    42.4              Double.valueOf(1)
    42.5          );
    42.6      }
    42.7 +
    42.8 +    @Test public void jsCallingConvention() throws Exception {
    42.9 +        assertExec(
   42.10 +            "Pointer to 'this' is passed automatically (and not as a first argument)",
   42.11 +            Instance.class, "jscall__I",
   42.12 +            Double.valueOf(31)
   42.13 +        );
   42.14 +    }
   42.15      
   42.16      protected String startCompilationWith() {
   42.17          return "org/apidesign/vm4brwsr/Instance";
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java	Wed Jan 16 12:27:53 2013 +0100
    43.3 @@ -0,0 +1,102 @@
    43.4 +/**
    43.5 + * Back 2 Browser Bytecode Translator
    43.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    43.7 + *
    43.8 + * This program is free software: you can redistribute it and/or modify
    43.9 + * it under the terms of the GNU General Public License as published by
   43.10 + * the Free Software Foundation, version 2 of the License.
   43.11 + *
   43.12 + * This program is distributed in the hope that it will be useful,
   43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.15 + * GNU General Public License for more details.
   43.16 + *
   43.17 + * You should have received a copy of the GNU General Public License
   43.18 + * along with this program. Look for COPYING file in the top folder.
   43.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   43.20 + */
   43.21 +package org.apidesign.bck2brwsr.tck;
   43.22 +
   43.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   43.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   43.25 +import org.testng.annotations.Factory;
   43.26 +
   43.27 +/**
   43.28 + *
   43.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   43.30 + */
   43.31 +public class ByteArithmeticTest {
   43.32 +    
   43.33 +    private static byte add(byte x, byte y) {
   43.34 +        return (byte)(x + y);
   43.35 +    }
   43.36 +    
   43.37 +    private static byte sub(byte x, byte y) {
   43.38 +        return (byte)(x - y);
   43.39 +    }
   43.40 +    
   43.41 +    private static byte mul(byte x, byte y) {
   43.42 +        return (byte)(x * y);
   43.43 +    }
   43.44 +    
   43.45 +    private static byte div(byte x, byte y) {
   43.46 +        return (byte)(x / y);
   43.47 +    }
   43.48 +    
   43.49 +    private static byte mod(byte x, byte y) {
   43.50 +        return (byte)(x % y);
   43.51 +    }
   43.52 +    
   43.53 +    @Compare public byte conversion() {
   43.54 +        return (byte)123456;
   43.55 +    }
   43.56 +    
   43.57 +    @Compare public byte addOverflow() {
   43.58 +        return add(Byte.MAX_VALUE, (byte)1);
   43.59 +    }
   43.60 +    
   43.61 +    @Compare public byte subUnderflow() {
   43.62 +        return sub(Byte.MIN_VALUE, (byte)1);
   43.63 +    }
   43.64 +    
   43.65 +    @Compare public byte addMaxByteAndMaxByte() {
   43.66 +        return add(Byte.MAX_VALUE, Byte.MAX_VALUE);
   43.67 +    }
   43.68 +    
   43.69 +    @Compare public byte subMinByteAndMinByte() {
   43.70 +        return sub(Byte.MIN_VALUE, Byte.MIN_VALUE);
   43.71 +    }
   43.72 +    
   43.73 +    @Compare public byte multiplyMaxByte() {
   43.74 +        return mul(Byte.MAX_VALUE, (byte)2);
   43.75 +    }
   43.76 +    
   43.77 +    @Compare public byte multiplyMaxByteAndMaxByte() {
   43.78 +        return mul(Byte.MAX_VALUE, Byte.MAX_VALUE);
   43.79 +    }
   43.80 +    
   43.81 +    @Compare public byte multiplyMinByte() {
   43.82 +        return mul(Byte.MIN_VALUE, (byte)2);
   43.83 +    }
   43.84 +    
   43.85 +    @Compare public byte multiplyMinByteAndMinByte() {
   43.86 +        return mul(Byte.MIN_VALUE, Byte.MIN_VALUE);
   43.87 +    }
   43.88 +    
   43.89 +    @Compare public byte multiplyPrecision() {
   43.90 +        return mul((byte)17638, (byte)1103);
   43.91 +    }
   43.92 +    
   43.93 +    @Compare public byte division() {
   43.94 +        return div((byte)1, (byte)2);
   43.95 +    }
   43.96 +    
   43.97 +    @Compare public byte divisionReminder() {
   43.98 +        return mod((byte)1, (byte)2);
   43.99 +    }
  43.100 +    
  43.101 +    @Factory
  43.102 +    public static Object[] create() {
  43.103 +        return VMTest.create(ByteArithmeticTest.class);
  43.104 +    }
  43.105 +}
    44.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Wed Jan 16 12:25:50 2013 +0100
    44.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Wed Jan 16 12:27:53 2013 +0100
    44.3 @@ -49,6 +49,36 @@
    44.4          return sum;
    44.5      }
    44.6      
    44.7 +    @Compare public String noOutOfBounds() {
    44.8 +        return atIndex(1);
    44.9 +    }
   44.10 +
   44.11 +    @Compare public String outOfBounds() {
   44.12 +        return atIndex(5);
   44.13 +    }
   44.14 +
   44.15 +    @Compare public String outOfBoundsMinus() {
   44.16 +        return atIndex(-1);
   44.17 +    }
   44.18 +
   44.19 +    @Compare public String toOfBounds() {
   44.20 +        return toIndex(5);
   44.21 +    }
   44.22 +
   44.23 +    @Compare public String toOfBoundsMinus() {
   44.24 +        return toIndex(-1);
   44.25 +    }
   44.26 +
   44.27 +    private static final int[] arr = { 0, 1, 2 };
   44.28 +    public static String atIndex(int at) {
   44.29 +        return "at@" + arr[at];
   44.30 +    }
   44.31 +    public static String toIndex(int at) {
   44.32 +        arr[at] = 10;
   44.33 +        return "ok";
   44.34 +    }
   44.35 +    
   44.36 +    
   44.37      @Factory
   44.38      public static Object[] create() {
   44.39          return VMTest.create(CompareByteArrayTest.class);
    45.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Wed Jan 16 12:25:50 2013 +0100
    45.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Wed Jan 16 12:27:53 2013 +0100
    45.3 @@ -39,6 +39,10 @@
    45.4          return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
    45.5      }
    45.6      
    45.7 +    @Compare public int hashOfInt() {
    45.8 +        return Integer.valueOf(Integer.MAX_VALUE).hashCode();
    45.9 +    }
   45.10 +    
   45.11      @Factory
   45.12      public static Object[] create() {
   45.13          return VMTest.create(CompareHashTest.class);
    46.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Wed Jan 16 12:25:50 2013 +0100
    46.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Wed Jan 16 12:27:53 2013 +0100
    46.3 @@ -28,6 +28,20 @@
    46.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
    46.5   */
    46.6  public class CompareStringsTest {
    46.7 +    @Compare public String firstChar() {
    46.8 +        return "" + ("Hello".toCharArray()[0]);
    46.9 +    }
   46.10 +    
   46.11 +    @Compare public String classCast() {
   46.12 +        Object o = firstChar();
   46.13 +        return String.class.cast(o);
   46.14 +    }
   46.15 +
   46.16 +    @Compare public String classCastThrown() {
   46.17 +        Object o = null;
   46.18 +        return String.class.cast(o);
   46.19 +    }
   46.20 +    
   46.21      @Compare public static Object compareURLs() throws MalformedURLException {
   46.22          return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   46.23      }
   46.24 @@ -76,6 +90,11 @@
   46.25          return "Hello".matches("Hell");
   46.26      }
   46.27      
   46.28 +    @Compare public String emptyCharArray() {
   46.29 +        char[] arr = new char[10];
   46.30 +        return new String(arr);
   46.31 +    }
   46.32 +    
   46.33      @Compare public String variousCharacterTests() throws Exception {
   46.34          StringBuilder sb = new StringBuilder();
   46.35          
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Wed Jan 16 12:27:53 2013 +0100
    47.3 @@ -0,0 +1,108 @@
    47.4 +/**
    47.5 + * Back 2 Browser Bytecode Translator
    47.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    47.7 + *
    47.8 + * This program is free software: you can redistribute it and/or modify
    47.9 + * it under the terms of the GNU General Public License as published by
   47.10 + * the Free Software Foundation, version 2 of the License.
   47.11 + *
   47.12 + * This program is distributed in the hope that it will be useful,
   47.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.15 + * GNU General Public License for more details.
   47.16 + *
   47.17 + * You should have received a copy of the GNU General Public License
   47.18 + * along with this program. Look for COPYING file in the top folder.
   47.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   47.20 + */
   47.21 +package org.apidesign.bck2brwsr.tck;
   47.22 +
   47.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   47.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   47.25 +import org.testng.annotations.Factory;
   47.26 +
   47.27 +/**
   47.28 + *
   47.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   47.30 + */
   47.31 +public class IntegerArithmeticTest {
   47.32 +    
   47.33 +    private static int add(int x, int y) {
   47.34 +        return x + y;
   47.35 +    }
   47.36 +    
   47.37 +    private static int sub(int x, int y) {
   47.38 +        return x - y;
   47.39 +    }
   47.40 +    
   47.41 +    private static int mul(int x, int y) {
   47.42 +        return x * y;
   47.43 +    }
   47.44 +    
   47.45 +    private static int div(int x, int y) {
   47.46 +        return x / y;
   47.47 +    }
   47.48 +    
   47.49 +    private static int mod(int x, int y) {
   47.50 +        return x % y;
   47.51 +    }
   47.52 +    
   47.53 +    @Compare public int addOverflow() {
   47.54 +        return add(Integer.MAX_VALUE, 1);
   47.55 +    }
   47.56 +    
   47.57 +    @Compare public int subUnderflow() {
   47.58 +        return sub(Integer.MIN_VALUE, 1);
   47.59 +    }
   47.60 +    
   47.61 +    @Compare public int addMaxIntAndMaxInt() {
   47.62 +        return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
   47.63 +    }
   47.64 +    
   47.65 +    @Compare public int subMinIntAndMinInt() {
   47.66 +        return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
   47.67 +    }
   47.68 +    
   47.69 +    @Compare public int multiplyMaxInt() {
   47.70 +        return mul(Integer.MAX_VALUE, 2);
   47.71 +    }
   47.72 +    
   47.73 +    @Compare public int multiplyMaxIntAndMaxInt() {
   47.74 +        return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
   47.75 +    }
   47.76 +    
   47.77 +    @Compare public int multiplyMinInt() {
   47.78 +        return mul(Integer.MIN_VALUE, 2);
   47.79 +    }
   47.80 +    
   47.81 +    @Compare public int multiplyMinIntAndMinInt() {
   47.82 +        return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
   47.83 +    }
   47.84 +    
   47.85 +    @Compare public int multiplyPrecision() {
   47.86 +        return mul(119106029, 1103515245);
   47.87 +    }
   47.88 +    
   47.89 +    @Compare public int division() {
   47.90 +        return div(1, 2);
   47.91 +    }
   47.92 +    
   47.93 +    @Compare public int divisionReminder() {
   47.94 +        return mod(1, 2);
   47.95 +    }
   47.96 +    
   47.97 +    @Compare public int sumTwoDimensions() {
   47.98 +        int[][] matrix = createMatrix(4, 3);
   47.99 +        matrix[0][0] += 10;
  47.100 +        return matrix[0][0];
  47.101 +    }
  47.102 +    
  47.103 +    static int[][] createMatrix(int x, int y) {
  47.104 +        return new int[x][y];
  47.105 +    }
  47.106 +    
  47.107 +    @Factory
  47.108 +    public static Object[] create() {
  47.109 +        return VMTest.create(IntegerArithmeticTest.class);
  47.110 +    }
  47.111 +}
    48.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Wed Jan 16 12:25:50 2013 +0100
    48.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Wed Jan 16 12:27:53 2013 +0100
    48.3 @@ -21,6 +21,8 @@
    48.4  import java.util.Arrays;
    48.5  import java.util.Collections;
    48.6  import java.util.List;
    48.7 +import java.util.logging.Level;
    48.8 +import java.util.logging.Logger;
    48.9  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   48.10  import org.apidesign.bck2brwsr.vmtest.Compare;
   48.11  import org.apidesign.bck2brwsr.vmtest.VMTest;
   48.12 @@ -90,6 +92,86 @@
   48.13          return (Integer)plus.invoke(null, 2, 3);
   48.14      }
   48.15      
   48.16 +    @Compare public String classGetNameForByte() {
   48.17 +         return byte.class.getName();
   48.18 +    }
   48.19 +    @Compare public String classGetNameForBaseObject() {
   48.20 +        return newObject().getClass().getName();
   48.21 +    }
   48.22 +    @Compare public String classGetNameForJavaObject() {
   48.23 +        return new Object().getClass().getName();
   48.24 +    }
   48.25 +    @Compare public String classGetNameForObjectArray() {
   48.26 +        return (new Object[3]).getClass().getName();
   48.27 +    }
   48.28 +    @Compare public String classGetNameForSimpleIntArray() {
   48.29 +        return (new int[3]).getClass().getName();
   48.30 +    }
   48.31 +    @Compare public boolean sameClassGetNameForSimpleCharArray() {
   48.32 +        return (new char[3]).getClass() == (new char[34]).getClass();
   48.33 +    }
   48.34 +    @Compare public String classGetNameForMultiIntArray() {
   48.35 +        return (new int[3][4][5][6][7][8][9]).getClass().getName();
   48.36 +    }
   48.37 +    @Compare public String classGetNameForMultiIntArrayInner() {
   48.38 +        final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
   48.39 +        int[][][][][][] subarr = arr[0];
   48.40 +        int[][][][][] subsubarr = subarr[0];
   48.41 +        return subsubarr.getClass().getName();
   48.42 +    }
   48.43 +    @Compare public String classGetNameForMultiStringArray() {
   48.44 +        return (new String[3][4][5][6][7][8][9]).getClass().getName();
   48.45 +    }
   48.46 +    
   48.47 +    @Compare public String classForByte() throws Exception {
   48.48 +        return Class.forName("[Z").getName();
   48.49 +    }
   48.50 +
   48.51 +    @Compare public String classForUnknownArray() {
   48.52 +        try {
   48.53 +            return Class.forName("[W").getName();
   48.54 +        } catch (Exception ex) {
   48.55 +            return ex.getClass().getName();
   48.56 +        }
   48.57 +    }
   48.58 +    
   48.59 +    @Compare public String classForUnknownDeepArray() {
   48.60 +        try {
   48.61 +            return Class.forName("[[[[[W").getName();
   48.62 +        } catch (Exception ex) {
   48.63 +            return ex.getClass().getName();
   48.64 +        }
   48.65 +    }
   48.66 +    
   48.67 +    @Compare public String componentGetNameForObjectArray() {
   48.68 +        return (new Object[3]).getClass().getComponentType().getName();
   48.69 +    }
   48.70 +    @Compare public boolean sameComponentGetNameForObjectArray() {
   48.71 +        return (new Object[3]).getClass().getComponentType() == Object.class;
   48.72 +    }
   48.73 +    @Compare public String componentGetNameForSimpleIntArray() {
   48.74 +        return (new int[3]).getClass().getComponentType().getName();
   48.75 +    }
   48.76 +    @Compare public String componentGetNameForMultiIntArray() {
   48.77 +        return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
   48.78 +    }
   48.79 +    @Compare public String componentGetNameForMultiStringArray() {
   48.80 +        Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
   48.81 +        StringBuilder sb = new StringBuilder();
   48.82 +        for (;;) {
   48.83 +            sb.append(c.getName()).append("\n");
   48.84 +            c = c.getComponentType();
   48.85 +            if (c == null) {
   48.86 +                break;
   48.87 +            }
   48.88 +        }
   48.89 +        return sb.toString();
   48.90 +    }
   48.91 +    
   48.92 +    @Compare public boolean isArray() {
   48.93 +        return new Object[0].getClass().isArray();
   48.94 +    }
   48.95 +    
   48.96      @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
   48.97      private static String[] sort(String[] arr, int len) {
   48.98          List<String> list = Arrays.asList(arr).subList(0, len);
   48.99 @@ -97,6 +179,11 @@
  48.100          return list.toArray(new String[0]);
  48.101      }
  48.102      
  48.103 +    @JavaScriptBody(args = {}, body = "return new Object();")
  48.104 +    private static Object newObject() {
  48.105 +        return new Object();
  48.106 +    }
  48.107 +    
  48.108      @Factory
  48.109      public static Object[] create() {
  48.110          return VMTest.create(ReflectionTest.class);
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Wed Jan 16 12:27:53 2013 +0100
    49.3 @@ -0,0 +1,45 @@
    49.4 +/**
    49.5 + * Back 2 Browser Bytecode Translator
    49.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    49.7 + *
    49.8 + * This program is free software: you can redistribute it and/or modify
    49.9 + * it under the terms of the GNU General Public License as published by
   49.10 + * the Free Software Foundation, version 2 of the License.
   49.11 + *
   49.12 + * This program is distributed in the hope that it will be useful,
   49.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.15 + * GNU General Public License for more details.
   49.16 + *
   49.17 + * You should have received a copy of the GNU General Public License
   49.18 + * along with this program. Look for COPYING file in the top folder.
   49.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   49.20 + */
   49.21 +package org.apidesign.bck2brwsr.tck;
   49.22 +
   49.23 +import java.io.InputStream;
   49.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   49.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   49.26 +import org.testng.annotations.Factory;
   49.27 +
   49.28 +/**
   49.29 + *
   49.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   49.31 + */
   49.32 +public class ResourcesTest {
   49.33 +    
   49.34 +    @Compare public String readResourceAsStream() throws Exception {
   49.35 +        InputStream is = getClass().getResourceAsStream("Resources.txt");
   49.36 +        byte[] b = new byte[30];
   49.37 +        int len = is.read(b);
   49.38 +        StringBuilder sb = new StringBuilder();
   49.39 +        for (int i = 0; i < len; i++) {
   49.40 +            sb.append((char)b[i]);
   49.41 +        }
   49.42 +        return sb.toString();
   49.43 +    }
   49.44 +    
   49.45 +    @Factory public static Object[] create() {
   49.46 +        return VMTest.create(ResourcesTest.class);
   49.47 +    }
   49.48 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ShortArithmeticTest.java	Wed Jan 16 12:27:53 2013 +0100
    50.3 @@ -0,0 +1,102 @@
    50.4 +/**
    50.5 + * Back 2 Browser Bytecode Translator
    50.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    50.7 + *
    50.8 + * This program is free software: you can redistribute it and/or modify
    50.9 + * it under the terms of the GNU General Public License as published by
   50.10 + * the Free Software Foundation, version 2 of the License.
   50.11 + *
   50.12 + * This program is distributed in the hope that it will be useful,
   50.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.15 + * GNU General Public License for more details.
   50.16 + *
   50.17 + * You should have received a copy of the GNU General Public License
   50.18 + * along with this program. Look for COPYING file in the top folder.
   50.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   50.20 + */
   50.21 +package org.apidesign.bck2brwsr.tck;
   50.22 +
   50.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   50.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   50.25 +import org.testng.annotations.Factory;
   50.26 +
   50.27 +/**
   50.28 + *
   50.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   50.30 + */
   50.31 +public class ShortArithmeticTest {
   50.32 +    
   50.33 +    private static short add(short x, short y) {
   50.34 +        return (short)(x + y);
   50.35 +    }
   50.36 +    
   50.37 +    private static short sub(short x, short y) {
   50.38 +        return (short)(x - y);
   50.39 +    }
   50.40 +    
   50.41 +    private static short mul(short x, short y) {
   50.42 +        return (short)(x * y);
   50.43 +    }
   50.44 +    
   50.45 +    private static short div(short x, short y) {
   50.46 +        return (short)(x / y);
   50.47 +    }
   50.48 +    
   50.49 +    private static short mod(short x, short y) {
   50.50 +        return (short)(x % y);
   50.51 +    }
   50.52 +    
   50.53 +    @Compare public short conversion() {
   50.54 +        return (short)123456;
   50.55 +    }
   50.56 +    
   50.57 +    @Compare public short addOverflow() {
   50.58 +        return add(Short.MAX_VALUE, (short)1);
   50.59 +    }
   50.60 +    
   50.61 +    @Compare public short subUnderflow() {
   50.62 +        return sub(Short.MIN_VALUE, (short)1);
   50.63 +    }
   50.64 +    
   50.65 +    @Compare public short addMaxShortAndMaxShort() {
   50.66 +        return add(Short.MAX_VALUE, Short.MAX_VALUE);
   50.67 +    }
   50.68 +    
   50.69 +    @Compare public short subMinShortAndMinShort() {
   50.70 +        return sub(Short.MIN_VALUE, Short.MIN_VALUE);
   50.71 +    }
   50.72 +    
   50.73 +    @Compare public short multiplyMaxShort() {
   50.74 +        return mul(Short.MAX_VALUE, (short)2);
   50.75 +    }
   50.76 +    
   50.77 +    @Compare public short multiplyMaxShortAndMaxShort() {
   50.78 +        return mul(Short.MAX_VALUE, Short.MAX_VALUE);
   50.79 +    }
   50.80 +    
   50.81 +    @Compare public short multiplyMinShort() {
   50.82 +        return mul(Short.MIN_VALUE, (short)2);
   50.83 +    }
   50.84 +    
   50.85 +    @Compare public short multiplyMinShortAndMinShort() {
   50.86 +        return mul(Short.MIN_VALUE, Short.MIN_VALUE);
   50.87 +    }
   50.88 +    
   50.89 +    @Compare public short multiplyPrecision() {
   50.90 +        return mul((short)17638, (short)1103);
   50.91 +    }
   50.92 +    
   50.93 +    @Compare public short division() {
   50.94 +        return div((short)1, (short)2);
   50.95 +    }
   50.96 +    
   50.97 +    @Compare public short divisionReminder() {
   50.98 +        return mod((short)1, (short)2);
   50.99 +    }
  50.100 +    
  50.101 +    @Factory
  50.102 +    public static Object[] create() {
  50.103 +        return VMTest.create(ShortArithmeticTest.class);
  50.104 +    }
  50.105 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt	Wed Jan 16 12:27:53 2013 +0100
    51.3 @@ -0,0 +1,1 @@
    51.4 +Ahoj