merge with trunk arithmetic
authorMartin Soch <Martin.Soch@oracle.com>
Mon, 21 Jan 2013 15:57:01 +0100
brancharithmetic
changeset 58195753ad65192
parent 454 6506c5925775
parent 504 974bc55865c7
child 582 8e546d108658
merge with trunk
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java
     1.1 --- a/core/pom.xml	Tue Jan 15 11:39:15 2013 +0100
     1.2 +++ b/core/pom.xml	Mon Jan 21 15:57:01 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	Mon Jan 21 15:57:01 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	Tue Jan 15 11:39:15 2013 +0100
     3.2 +++ b/emul/src/main/java/java/lang/Class.java	Mon Jan 21 15:57:01 2013 +0100
     3.3 @@ -145,7 +145,15 @@
     3.4       * @exception ClassNotFoundException if the class cannot be located
     3.5       */
     3.6      public static Class<?> forName(String className)
     3.7 -                throws ClassNotFoundException {
     3.8 +    throws ClassNotFoundException {
     3.9 +        if (className.startsWith("[")) {
    3.10 +            Class<?> arrType = defineArray(className);
    3.11 +            Class<?> c = arrType;
    3.12 +            while (c != null && c.isArray()) {
    3.13 +                c = c.getComponentType0(); // verify component type is sane
    3.14 +            }
    3.15 +            return arrType;
    3.16 +        }
    3.17          Class<?> c = loadCls(className, className.replace('.', '_'));
    3.18          if (c == null) {
    3.19              throw new ClassNotFoundException(className);
    3.20 @@ -216,7 +224,7 @@
    3.21          + "\nif (c['cons__V']) {"
    3.22          + "\n  if ((c.cons__V.access & 0x1) != 0) {"
    3.23          + "\n    var inst = c();"
    3.24 -        + "\n    c.cons__V(inst);"
    3.25 +        + "\n    c.cons__V.call(inst);"
    3.26          + "\n    return inst;"
    3.27          + "\n  }"
    3.28          + "\n  return illegal;"
    3.29 @@ -269,7 +277,15 @@
    3.30       *
    3.31       * @since JDK1.1
    3.32       */
    3.33 -    public native boolean isInstance(Object obj);
    3.34 +    public boolean isInstance(Object obj) {
    3.35 +        String prop = "$instOf_" + getName().replace('.', '_');
    3.36 +        return hasProperty(obj, prop);
    3.37 +    }
    3.38 +    
    3.39 +    @JavaScriptBody(args = { "who", "prop" }, body = 
    3.40 +        "if (who[prop]) return true; else return false;"
    3.41 +    )
    3.42 +    private static native boolean hasProperty(Object who, String prop);
    3.43  
    3.44  
    3.45      /**
    3.46 @@ -310,7 +326,7 @@
    3.47          return (getAccess() & 0x200) != 0;
    3.48      }
    3.49      
    3.50 -    @JavaScriptBody(args = "self", body = "return self.access;")
    3.51 +    @JavaScriptBody(args = {}, body = "return this.access;")
    3.52      private native int getAccess();
    3.53  
    3.54  
    3.55 @@ -322,7 +338,7 @@
    3.56       * @since   JDK1.1
    3.57       */
    3.58      public boolean isArray() {
    3.59 -        return false;
    3.60 +        return hasProperty(this, "array"); // NOI18N
    3.61      }
    3.62  
    3.63  
    3.64 @@ -354,8 +370,8 @@
    3.65       * @see     java.lang.Void#TYPE
    3.66       * @since JDK1.1
    3.67       */
    3.68 -    @JavaScriptBody(args = "self", body = 
    3.69 -           "if (self.primitive) return true;"
    3.70 +    @JavaScriptBody(args = {}, body = 
    3.71 +           "if (this.primitive) return true;"
    3.72          + "else return false;"
    3.73      )
    3.74      public native boolean isPrimitive();
    3.75 @@ -439,7 +455,7 @@
    3.76          return jvmName().replace('/', '.');
    3.77      }
    3.78  
    3.79 -    @JavaScriptBody(args = "self", body = "return self.jvmName;")
    3.80 +    @JavaScriptBody(args = {}, body = "return this.jvmName;")
    3.81      private native String jvmName();
    3.82  
    3.83      
    3.84 @@ -473,7 +489,7 @@
    3.85       *
    3.86       * @return the superclass of the class represented by this object.
    3.87       */
    3.88 -    @JavaScriptBody(args = "self", body = "return self.superclass;")
    3.89 +    @JavaScriptBody(args = {}, body = "return this.superclass;")
    3.90      public native Class<? super T> getSuperclass();
    3.91  
    3.92      /**
    3.93 @@ -1002,9 +1018,59 @@
    3.94       * @since JDK1.1
    3.95       */
    3.96      public Class<?> getComponentType() {
    3.97 +        if (isArray()) {
    3.98 +            try {
    3.99 +                return getComponentType0();
   3.100 +            } catch (ClassNotFoundException cnfe) {
   3.101 +                throw new IllegalStateException(cnfe);
   3.102 +            }
   3.103 +        }
   3.104          return null;
   3.105      }
   3.106  
   3.107 +    private Class<?> getComponentType0() throws ClassNotFoundException {
   3.108 +        String n = getName().substring(1);
   3.109 +        switch (n.charAt(0)) {
   3.110 +            case 'L': 
   3.111 +                n = n.substring(1, n.length() - 1);
   3.112 +                return Class.forName(n);
   3.113 +            case 'I':
   3.114 +                return Integer.TYPE;
   3.115 +            case 'J':
   3.116 +                return Long.TYPE;
   3.117 +            case 'D':
   3.118 +                return Double.TYPE;
   3.119 +            case 'F':
   3.120 +                return Float.TYPE;
   3.121 +            case 'B':
   3.122 +                return Byte.TYPE;
   3.123 +            case 'Z':
   3.124 +                return Boolean.TYPE;
   3.125 +            case 'S':
   3.126 +                return Short.TYPE;
   3.127 +            case 'V':
   3.128 +                return Void.TYPE;
   3.129 +            case 'C':
   3.130 +                return Character.TYPE;
   3.131 +            case '[':
   3.132 +                return defineArray(n);
   3.133 +            default:
   3.134 +                throw new ClassNotFoundException("Unknown component type of " + getName());
   3.135 +        }
   3.136 +    }
   3.137 +    
   3.138 +    @JavaScriptBody(args = { "sig" }, body = 
   3.139 +        "var c = Array[sig];\n" +
   3.140 +        "if (c) return c;\n" +
   3.141 +        "c = vm.java_lang_Class(true);\n" +
   3.142 +        "c.jvmName = sig;\n" +
   3.143 +        "c.superclass = vm.java_lang_Object(false).$class;\n" +
   3.144 +        "c.array = true;\n" +
   3.145 +        "Array[sig] = c;\n" +
   3.146 +        "return c;"
   3.147 +    )
   3.148 +    private static native Class<?> defineArray(String sig);
   3.149 +    
   3.150      /**
   3.151       * Returns true if and only if this class was declared as an enum in the
   3.152       * source code.
   3.153 @@ -1070,10 +1136,10 @@
   3.154              throw new ClassCastException(this.toString());
   3.155      }
   3.156  
   3.157 -    @JavaScriptBody(args = { "self", "ac" }, 
   3.158 +    @JavaScriptBody(args = { "ac" }, 
   3.159          body = 
   3.160 -          "if (self.anno) {"
   3.161 -        + "  return self.anno['L' + ac.jvmName + ';'];"
   3.162 +          "if (this.anno) {"
   3.163 +        + "  return this.anno['L' + ac.jvmName + ';'];"
   3.164          + "} else return null;"
   3.165      )
   3.166      private Object getAnnotationData(Class<?> annotationClass) {
   3.167 @@ -1092,8 +1158,8 @@
   3.168       * @throws NullPointerException {@inheritDoc}
   3.169       * @since 1.5
   3.170       */
   3.171 -    @JavaScriptBody(args = { "self", "ac" }, 
   3.172 -        body = "if (self.anno && self.anno['L' + ac.jvmName + ';']) { return true; }"
   3.173 +    @JavaScriptBody(args = { "ac" }, 
   3.174 +        body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
   3.175          + "else return false;"
   3.176      )
   3.177      public boolean isAnnotationPresent(
   3.178 @@ -1104,7 +1170,7 @@
   3.179          return getAnnotation(annotationClass) != null;
   3.180      }
   3.181  
   3.182 -    @JavaScriptBody(args = "self", body = "return self.anno;")
   3.183 +    @JavaScriptBody(args = {}, body = "return this.anno;")
   3.184      private Object getAnnotationData() {
   3.185          throw new UnsupportedOperationException();
   3.186      }
     4.1 --- a/emul/src/main/java/java/lang/Double.java	Tue Jan 15 11:39:15 2013 +0100
     4.2 +++ b/emul/src/main/java/java/lang/Double.java	Mon Jan 21 15:57:01 2013 +0100
     4.3 @@ -774,8 +774,7 @@
     4.4       */
     4.5      public boolean equals(Object obj) {
     4.6          return (obj instanceof Double)
     4.7 -               && (doubleToLongBits(((Double)obj).value) ==
     4.8 -                      doubleToLongBits(value));
     4.9 +               && (((Double)obj).value) == value;
    4.10      }
    4.11  
    4.12      /**
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/emul/src/main/java/java/lang/NegativeArraySizeException.java	Mon Jan 21 15:57:01 2013 +0100
     5.3 @@ -0,0 +1,55 @@
     5.4 +/*
     5.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.  Oracle designates this
    5.11 + * particular file as subject to the "Classpath" exception as provided
    5.12 + * by Oracle in the LICENSE file that accompanied this code.
    5.13 + *
    5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 + * version 2 for more details (a copy is included in the LICENSE file that
    5.18 + * accompanied this code).
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License version
    5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 + *
    5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 + * or visit www.oracle.com if you need additional information or have any
    5.26 + * questions.
    5.27 + */
    5.28 +
    5.29 +package java.lang;
    5.30 +
    5.31 +/**
    5.32 + * Thrown if an application tries to create an array with negative size.
    5.33 + *
    5.34 + * @author  unascribed
    5.35 + * @since   JDK1.0
    5.36 + */
    5.37 +public
    5.38 +class NegativeArraySizeException extends RuntimeException {
    5.39 +    private static final long serialVersionUID = -8960118058596991861L;
    5.40 +
    5.41 +    /**
    5.42 +     * Constructs a <code>NegativeArraySizeException</code> with no
    5.43 +     * detail message.
    5.44 +     */
    5.45 +    public NegativeArraySizeException() {
    5.46 +        super();
    5.47 +    }
    5.48 +
    5.49 +    /**
    5.50 +     * Constructs a <code>NegativeArraySizeException</code> with the
    5.51 +     * specified detail message.
    5.52 +     *
    5.53 +     * @param   s   the detail message.
    5.54 +     */
    5.55 +    public NegativeArraySizeException(String s) {
    5.56 +        super(s);
    5.57 +    }
    5.58 +}
     6.1 --- a/emul/src/main/java/java/lang/Object.java	Tue Jan 15 11:39:15 2013 +0100
     6.2 +++ b/emul/src/main/java/java/lang/Object.java	Mon Jan 21 15:57:01 2013 +0100
     6.3 @@ -25,6 +25,7 @@
     6.4  
     6.5  package java.lang;
     6.6  
     6.7 +import java.lang.reflect.Array;
     6.8  import org.apidesign.bck2brwsr.core.JavaScriptBody;
     6.9  import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
    6.10  
    6.11 @@ -40,8 +41,13 @@
    6.12  @JavaScriptPrototype(container = "Object.prototype", prototype = "new Object")
    6.13  public class Object {
    6.14  
    6.15 -    @JavaScriptBody(args = {}, body = "")
    6.16 -    private static native void registerNatives();
    6.17 +    private static void registerNatives() {
    6.18 +        try {
    6.19 +            Array.get(null, 0);
    6.20 +        } catch (Throwable ex) {
    6.21 +            // ignore
    6.22 +        }
    6.23 +    }
    6.24      static {
    6.25          registerNatives();
    6.26      }
    6.27 @@ -66,7 +72,7 @@
    6.28       * @see    Class Literals, section 15.8.2 of
    6.29       *         <cite>The Java&trade; Language Specification</cite>.
    6.30       */
    6.31 -    @JavaScriptBody(args="self", body="return self.constructor.$class;")
    6.32 +    @JavaScriptBody(args={}, body="return this.constructor.$class;")
    6.33      public final native Class<?> getClass();
    6.34  
    6.35      /**
    6.36 @@ -104,14 +110,14 @@
    6.37       * @see     java.lang.Object#equals(java.lang.Object)
    6.38       * @see     java.lang.System#identityHashCode
    6.39       */
    6.40 -    @JavaScriptBody(args = "self", body = 
    6.41 -        "if (self.$hashCode) return self.$hashCode;\n"
    6.42 -        + "var h = self.computeHashCode__I(self);\n"
    6.43 -        + "return self.$hashCode = h & h;"
    6.44 +    @JavaScriptBody(args = {}, body = 
    6.45 +        "if (this.$hashCode) return this.$hashCode;\n"
    6.46 +        + "var h = this.computeHashCode__I();\n"
    6.47 +        + "return this.$hashCode = h & h;"
    6.48      )
    6.49      public native int hashCode();
    6.50  
    6.51 -    @JavaScriptBody(args = "self", body = "Math.random() * Math.pow(2, 32);")
    6.52 +    @JavaScriptBody(args = {}, body = "Math.random() * Math.pow(2, 32);")
    6.53      native int computeHashCode();
    6.54      
    6.55      /**
     7.1 --- a/emul/src/main/java/java/lang/String.java	Tue Jan 15 11:39:15 2013 +0100
     7.2 +++ b/emul/src/main/java/java/lang/String.java	Mon Jan 21 15:57:01 2013 +0100
     7.3 @@ -169,11 +169,11 @@
     7.4       * @param  value
     7.5       *         The initial value of the string
     7.6       */
     7.7 -    @JavaScriptBody(args = { "self", "charArr" }, body=
     7.8 +    @JavaScriptBody(args = { "charArr" }, body=
     7.9          "for (var i = 0; i < charArr.length; i++) {\n"
    7.10        + "  if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n"
    7.11        + "}\n"
    7.12 -      + "self.fld_r = charArr.join('');\n"
    7.13 +      + "this.fld_r = charArr.join('');\n"
    7.14      )
    7.15      public String(char value[]) {
    7.16      }
    7.17 @@ -199,12 +199,12 @@
    7.18       *          If the {@code offset} and {@code count} arguments index
    7.19       *          characters outside the bounds of the {@code value} array
    7.20       */
    7.21 -    @JavaScriptBody(args = { "self", "charArr", "off", "cnt" }, body =
    7.22 +    @JavaScriptBody(args = { "charArr", "off", "cnt" }, body =
    7.23          "var up = off + cnt;\n" +
    7.24          "for (var i = off; i < up; i++) {\n" +
    7.25          "  if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n" +
    7.26          "}\n" +
    7.27 -        "self.fld_r = charArr.slice(off, up).join(\"\");\n"
    7.28 +        "this.fld_r = charArr.slice(off, up).join(\"\");\n"
    7.29      )
    7.30      public String(char value[], int offset, int count) {
    7.31      }
    7.32 @@ -618,7 +618,7 @@
    7.33       * @return  the length of the sequence of characters represented by this
    7.34       *          object.
    7.35       */
    7.36 -    @JavaScriptBody(args = "self", body = "return self.toString().length;")
    7.37 +    @JavaScriptBody(args = {}, body = "return this.toString().length;")
    7.38      public int length() {
    7.39          throw new UnsupportedOperationException();
    7.40      }
    7.41 @@ -631,7 +631,7 @@
    7.42       *
    7.43       * @since 1.6
    7.44       */
    7.45 -    @JavaScriptBody(args = "self", body="return self.toString().length === 0;")
    7.46 +    @JavaScriptBody(args = {}, body="return this.toString().length === 0;")
    7.47      public boolean isEmpty() {
    7.48          return length() == 0;
    7.49      }
    7.50 @@ -654,8 +654,8 @@
    7.51       *             argument is negative or not less than the length of this
    7.52       *             string.
    7.53       */
    7.54 -    @JavaScriptBody(args = { "self", "index" }, 
    7.55 -        body = "return self.toString().charCodeAt(index);"
    7.56 +    @JavaScriptBody(args = { "index" }, 
    7.57 +        body = "return this.toString().charCodeAt(index);"
    7.58      )
    7.59      public char charAt(int index) {
    7.60          throw new UnsupportedOperationException();
    7.61 @@ -780,8 +780,8 @@
    7.62       * Copy characters from this string into dst starting at dstBegin.
    7.63       * This method doesn't perform any range checking.
    7.64       */
    7.65 -    @JavaScriptBody(args = { "self", "arr", "to" }, body = 
    7.66 -        "var s = self.toString();\n" +
    7.67 +    @JavaScriptBody(args = { "arr", "to" }, body = 
    7.68 +        "var s = this.toString();\n" +
    7.69          "for (var i = 0; i < s.length; i++) {\n" +
    7.70          "   arr[to++] = s[i];\n" +
    7.71          "}"
    7.72 @@ -820,8 +820,8 @@
    7.73       *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
    7.74       *                <code>dst.length</code></ul>
    7.75       */
    7.76 -    @JavaScriptBody(args = { "self", "beg", "end", "arr", "dst" }, body=
    7.77 -        "var s = self.toString();\n" +
    7.78 +    @JavaScriptBody(args = { "beg", "end", "arr", "dst" }, body=
    7.79 +        "var s = this.toString();\n" +
    7.80          "while (beg < end) {\n" +
    7.81          "  arr[dst++] = s[beg++];\n" +
    7.82          "}\n"
    7.83 @@ -993,9 +993,9 @@
    7.84       * @see  #compareTo(String)
    7.85       * @see  #equalsIgnoreCase(String)
    7.86       */
    7.87 -    @JavaScriptBody(args = { "self", "obj" }, body = 
    7.88 -        "return obj.$instOf_java_lang_String && "
    7.89 -        + "self.toString() === obj.toString();"
    7.90 +    @JavaScriptBody(args = { "obj" }, body = 
    7.91 +        "return obj != null && obj.$instOf_java_lang_String && "
    7.92 +        + "this.toString() === obj.toString();"
    7.93      )
    7.94      public boolean equals(Object anObject) {
    7.95          if (this == anObject) {
    7.96 @@ -1420,9 +1420,9 @@
    7.97       *          this.substring(toffset).startsWith(prefix)
    7.98       *          </pre>
    7.99       */
   7.100 -    @JavaScriptBody(args = { "self", "find", "from" }, body=
   7.101 +    @JavaScriptBody(args = { "find", "from" }, body=
   7.102          "find = find.toString();\n" +
   7.103 -        "return self.toString().substring(from, from + find.length) === find;\n"
   7.104 +        "return this.toString().substring(from, from + find.length) === find;\n"
   7.105      )
   7.106      public boolean startsWith(String prefix, int toffset) {
   7.107          char ta[] = toCharArray();
   7.108 @@ -1570,9 +1570,9 @@
   7.109       *          than or equal to <code>fromIndex</code>, or <code>-1</code>
   7.110       *          if the character does not occur.
   7.111       */
   7.112 -    @JavaScriptBody(args = { "self", "ch", "from" }, body = 
   7.113 +    @JavaScriptBody(args = { "ch", "from" }, body = 
   7.114          "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
   7.115 -        "return self.toString().indexOf(ch, from);\n"
   7.116 +        "return this.toString().indexOf(ch, from);\n"
   7.117      )
   7.118      public int indexOf(int ch, int fromIndex) {
   7.119          if (fromIndex < 0) {
   7.120 @@ -1679,9 +1679,9 @@
   7.121       *          than or equal to <code>fromIndex</code>, or <code>-1</code>
   7.122       *          if the character does not occur before that point.
   7.123       */
   7.124 -    @JavaScriptBody(args = { "self", "ch", "from" }, body = 
   7.125 +    @JavaScriptBody(args = { "ch", "from" }, body = 
   7.126          "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
   7.127 -        "return self.toString().lastIndexOf(ch, from);"
   7.128 +        "return this.toString().lastIndexOf(ch, from);"
   7.129      )
   7.130      public int lastIndexOf(int ch, int fromIndex) {
   7.131          if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
   7.132 @@ -1754,8 +1754,8 @@
   7.133       *          starting at the specified index,
   7.134       *          or {@code -1} if there is no such occurrence.
   7.135       */
   7.136 -    @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
   7.137 -        "return self.toString().indexOf(str.toString(), fromIndex);"
   7.138 +    @JavaScriptBody(args = { "str", "fromIndex" }, body =
   7.139 +        "return this.toString().indexOf(str.toString(), fromIndex);"
   7.140      )
   7.141      public native int indexOf(String str, int fromIndex);
   7.142  
   7.143 @@ -1794,8 +1794,8 @@
   7.144       *          searching backward from the specified index,
   7.145       *          or {@code -1} if there is no such occurrence.
   7.146       */
   7.147 -    @JavaScriptBody(args = { "self", "s", "from" }, body = 
   7.148 -        "return self.toString().lastIndexOf(s.toString(), from);"
   7.149 +    @JavaScriptBody(args = { "s", "from" }, body = 
   7.150 +        "return this.toString().lastIndexOf(s.toString(), from);"
   7.151      )
   7.152      public int lastIndexOf(String str, int fromIndex) {
   7.153          return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
   7.154 @@ -1903,8 +1903,8 @@
   7.155       *             <code>beginIndex</code> is larger than
   7.156       *             <code>endIndex</code>.
   7.157       */
   7.158 -    @JavaScriptBody(args = { "self", "beginIndex", "endIndex" }, body = 
   7.159 -        "return self.toString().substring(beginIndex, endIndex);"
   7.160 +    @JavaScriptBody(args = { "beginIndex", "endIndex" }, body = 
   7.161 +        "return this.toString().substring(beginIndex, endIndex);"
   7.162      )
   7.163      public String substring(int beginIndex, int endIndex) {
   7.164          if (beginIndex < 0) {
   7.165 @@ -2012,10 +2012,10 @@
   7.166       * @return  a string derived from this string by replacing every
   7.167       *          occurrence of <code>oldChar</code> with <code>newChar</code>.
   7.168       */
   7.169 -    @JavaScriptBody(args = { "self", "arg1", "arg2" }, body =
   7.170 +    @JavaScriptBody(args = { "arg1", "arg2" }, body =
   7.171          "if (typeof arg1 === 'number') arg1 = String.fromCharCode(arg1);\n" +
   7.172          "if (typeof arg2 === 'number') arg2 = String.fromCharCode(arg2);\n" +
   7.173 -        "var s = self.toString();\n" +
   7.174 +        "var s = this.toString();\n" +
   7.175          "for (;;) {\n" +
   7.176          "  var ret = s.replace(arg1, arg2);\n" +
   7.177          "  if (ret === s) {\n" +
   7.178 @@ -2078,8 +2078,8 @@
   7.179       * @since 1.4
   7.180       * @spec JSR-51
   7.181       */
   7.182 -    @JavaScriptBody(args = { "self", "regex" }, body = 
   7.183 -          "self = self.toString();\n"
   7.184 +    @JavaScriptBody(args = { "regex" }, body = 
   7.185 +          "var self = this.toString();\n"
   7.186          + "var re = new RegExp(regex.toString());\n"
   7.187          + "var r = re.exec(self);\n"
   7.188          + "return r != null && r.length > 0 && self.length == r[0].length;"
   7.189 @@ -2496,7 +2496,7 @@
   7.190       * @return  the <code>String</code>, converted to lowercase.
   7.191       * @see     java.lang.String#toLowerCase(Locale)
   7.192       */
   7.193 -    @JavaScriptBody(args = "self", body = "return self.toLowerCase();")
   7.194 +    @JavaScriptBody(args = {}, body = "return this.toLowerCase();")
   7.195      public String toLowerCase() {
   7.196          throw new UnsupportedOperationException("Should be supported but without connection to locale");
   7.197      }
   7.198 @@ -2662,7 +2662,7 @@
   7.199       * @return  the <code>String</code>, converted to uppercase.
   7.200       * @see     java.lang.String#toUpperCase(Locale)
   7.201       */
   7.202 -    @JavaScriptBody(args = "self", body = "return self.toUpperCase();")
   7.203 +    @JavaScriptBody(args = {}, body = "return this.toUpperCase();")
   7.204      public String toUpperCase() {
   7.205          throw new UnsupportedOperationException();
   7.206      }
   7.207 @@ -2718,7 +2718,7 @@
   7.208       *
   7.209       * @return  the string itself.
   7.210       */
   7.211 -    @JavaScriptBody(args = "self", body = "return self.toString();")
   7.212 +    @JavaScriptBody(args = {}, body = "return this.toString();")
   7.213      public String toString() {
   7.214          return this;
   7.215      }
     8.1 --- a/emul/src/main/java/java/lang/Throwable.java	Tue Jan 15 11:39:15 2013 +0100
     8.2 +++ b/emul/src/main/java/java/lang/Throwable.java	Mon Jan 21 15:57:01 2013 +0100
     8.3 @@ -26,6 +26,7 @@
     8.4  package java.lang;
     8.5  import  java.io.*;
     8.6  import org.apidesign.bck2brwsr.core.JavaScriptBody;
     8.7 +import org.apidesign.bck2brwsr.core.JavaScriptOnly;
     8.8  
     8.9  /**
    8.10   * The {@code Throwable} class is the superclass of all errors and
    8.11 @@ -234,6 +235,13 @@
    8.12      private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
    8.13  
    8.14      /** Caption  for labeling causative exception stack traces */
    8.15 +    @JavaScriptOnly(name="toString", value="function() { return this.toString__Ljava_lang_String_2().toString(); }")
    8.16 +    private static void jsToString() {
    8.17 +    }
    8.18 +    
    8.19 +    @JavaScriptOnly(name="valueOf", value="function() { return this.toString().valueOf(); }")
    8.20 +    private static void jsValudOf() {
    8.21 +    }
    8.22      private static final String CAUSE_CAPTION = "Caused by: ";
    8.23  
    8.24      /** Caption for labeling suppressed exception stack traces */
    8.25 @@ -783,7 +791,7 @@
    8.26          return this;
    8.27      }
    8.28  
    8.29 -    @JavaScriptBody(args = { "self", "dummy" }, body = "")
    8.30 +    @JavaScriptBody(args = { "dummy" }, body = "")
    8.31      private native Throwable fillInStackTrace(int dummy);
    8.32  
    8.33      /**
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/emul/src/main/java/java/lang/reflect/Array.java	Mon Jan 21 15:57:01 2013 +0100
     9.3 @@ -0,0 +1,659 @@
     9.4 +/*
     9.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.  Oracle designates this
    9.11 + * particular file as subject to the "Classpath" exception as provided
    9.12 + * by Oracle in the LICENSE file that accompanied this code.
    9.13 + *
    9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 + * version 2 for more details (a copy is included in the LICENSE file that
    9.18 + * accompanied this code).
    9.19 + *
    9.20 + * You should have received a copy of the GNU General Public License version
    9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 + *
    9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 + * or visit www.oracle.com if you need additional information or have any
    9.26 + * questions.
    9.27 + */
    9.28 +
    9.29 +package java.lang.reflect;
    9.30 +
    9.31 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    9.32 +import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
    9.33 +
    9.34 +/**
    9.35 + * The {@code Array} class provides static methods to dynamically create and
    9.36 + * access Java arrays.
    9.37 + *
    9.38 + * <p>{@code Array} permits widening conversions to occur during a get or set
    9.39 + * operation, but throws an {@code IllegalArgumentException} if a narrowing
    9.40 + * conversion would occur.
    9.41 + *
    9.42 + * @author Nakul Saraiya
    9.43 + */
    9.44 +@JavaScriptPrototype(prototype = "new Array", container = "Array.prototype")
    9.45 +public final
    9.46 +class Array {
    9.47 +
    9.48 +    /**
    9.49 +     * Constructor.  Class Array is not instantiable.
    9.50 +     */
    9.51 +    private Array() {}
    9.52 +
    9.53 +    /**
    9.54 +     * Creates a new array with the specified component type and
    9.55 +     * length.
    9.56 +     * Invoking this method is equivalent to creating an array
    9.57 +     * as follows:
    9.58 +     * <blockquote>
    9.59 +     * <pre>
    9.60 +     * int[] x = {length};
    9.61 +     * Array.newInstance(componentType, x);
    9.62 +     * </pre>
    9.63 +     * </blockquote>
    9.64 +     *
    9.65 +     * @param componentType the {@code Class} object representing the
    9.66 +     * component type of the new array
    9.67 +     * @param length the length of the new array
    9.68 +     * @return the new array
    9.69 +     * @exception NullPointerException if the specified
    9.70 +     * {@code componentType} parameter is null
    9.71 +     * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
    9.72 +     * @exception NegativeArraySizeException if the specified {@code length}
    9.73 +     * is negative
    9.74 +     */
    9.75 +    public static Object newInstance(Class<?> componentType, int length)
    9.76 +    throws NegativeArraySizeException {
    9.77 +        if (length < 0) {
    9.78 +            throw new NegativeArraySizeException();
    9.79 +        }
    9.80 +        String sig = findSignature(componentType);
    9.81 +        return newArray(componentType.isPrimitive(), sig, length);
    9.82 +    }
    9.83 +    
    9.84 +    private static String findSignature(Class<?> type) {
    9.85 +        if (type == Integer.TYPE) {
    9.86 +            return "[I";
    9.87 +        }
    9.88 +        if (type == Long.TYPE) {
    9.89 +            return "[J";
    9.90 +        }
    9.91 +        if (type == Double.TYPE) {
    9.92 +            return "[D";
    9.93 +        }
    9.94 +        if (type == Float.TYPE) {
    9.95 +            return "[F";
    9.96 +        }
    9.97 +        if (type == Byte.TYPE) {
    9.98 +            return "[B";
    9.99 +        }
   9.100 +        if (type == Boolean.TYPE) {
   9.101 +            return "[Z";
   9.102 +        }
   9.103 +        if (type == Short.TYPE) {
   9.104 +            return "[S";
   9.105 +        }
   9.106 +        if (type == Character.TYPE) {
   9.107 +            return "[C";
   9.108 +        }
   9.109 +        if (type.getName().equals("void")) {
   9.110 +            throw new IllegalStateException("Can't create array for " + type);
   9.111 +        }
   9.112 +        return "[L" + type.getName() + ";";
   9.113 +    }
   9.114 +    /**
   9.115 +     * Creates a new array
   9.116 +     * with the specified component type and dimensions.
   9.117 +     * If {@code componentType}
   9.118 +     * represents a non-array class or interface, the new array
   9.119 +     * has {@code dimensions.length} dimensions and
   9.120 +     * {@code componentType} as its component type. If
   9.121 +     * {@code componentType} represents an array class, the
   9.122 +     * number of dimensions of the new array is equal to the sum
   9.123 +     * of {@code dimensions.length} and the number of
   9.124 +     * dimensions of {@code componentType}. In this case, the
   9.125 +     * component type of the new array is the component type of
   9.126 +     * {@code componentType}.
   9.127 +     *
   9.128 +     * <p>The number of dimensions of the new array must not
   9.129 +     * exceed the number of array dimensions supported by the
   9.130 +     * implementation (typically 255).
   9.131 +     *
   9.132 +     * @param componentType the {@code Class} object representing the component
   9.133 +     * type of the new array
   9.134 +     * @param dimensions an array of {@code int} representing the dimensions of
   9.135 +     * the new array
   9.136 +     * @return the new array
   9.137 +     * @exception NullPointerException if the specified
   9.138 +     * {@code componentType} argument is null
   9.139 +     * @exception IllegalArgumentException if the specified {@code dimensions}
   9.140 +     * argument is a zero-dimensional array, or if the number of
   9.141 +     * requested dimensions exceeds the limit on the number of array dimensions
   9.142 +     * supported by the implementation (typically 255), or if componentType
   9.143 +     * is {@link Void#TYPE}.
   9.144 +     * @exception NegativeArraySizeException if any of the components in
   9.145 +     * the specified {@code dimensions} argument is negative.
   9.146 +     */
   9.147 +    public static Object newInstance(Class<?> componentType, int... dimensions)
   9.148 +        throws IllegalArgumentException, NegativeArraySizeException {
   9.149 +        StringBuilder sig = new StringBuilder();
   9.150 +        for (int i = 1; i < dimensions.length; i++) {
   9.151 +            sig.append('[');
   9.152 +        }
   9.153 +        sig.append(findSignature(componentType));
   9.154 +        return multiNewArray(sig.toString(), dimensions, 0);
   9.155 +    }
   9.156 +
   9.157 +    /**
   9.158 +     * Returns the length of the specified array object, as an {@code int}.
   9.159 +     *
   9.160 +     * @param array the array
   9.161 +     * @return the length of the array
   9.162 +     * @exception IllegalArgumentException if the object argument is not
   9.163 +     * an array
   9.164 +     */
   9.165 +    public static int getLength(Object array)
   9.166 +    throws IllegalArgumentException {
   9.167 +        if (!array.getClass().isArray()) {
   9.168 +            throw new IllegalArgumentException("Argument is not an array");
   9.169 +        }
   9.170 +        return length(array);
   9.171 +    }
   9.172 +    
   9.173 +    @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
   9.174 +    private static native int length(Object arr);
   9.175 +
   9.176 +    /**
   9.177 +     * Returns the value of the indexed component in the specified
   9.178 +     * array object.  The value is automatically wrapped in an object
   9.179 +     * if it has a primitive type.
   9.180 +     *
   9.181 +     * @param array the array
   9.182 +     * @param index the index
   9.183 +     * @return the (possibly wrapped) value of the indexed component in
   9.184 +     * the specified array
   9.185 +     * @exception NullPointerException If the specified object is null
   9.186 +     * @exception IllegalArgumentException If the specified object is not
   9.187 +     * an array
   9.188 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.189 +     * argument is negative, or if it is greater than or equal to the
   9.190 +     * length of the specified array
   9.191 +     */
   9.192 +    public static Object get(Object array, int index)
   9.193 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.194 +        final Class<?> t = array.getClass().getComponentType();
   9.195 +        if (t.isPrimitive()) {
   9.196 +            return Array.fromPrimitive(t, array, index);
   9.197 +        } else {
   9.198 +            return ((Object[])array)[index];
   9.199 +        }
   9.200 +    }
   9.201 +
   9.202 +    /**
   9.203 +     * Returns the value of the indexed component in the specified
   9.204 +     * array object, as a {@code boolean}.
   9.205 +     *
   9.206 +     * @param array the array
   9.207 +     * @param index the index
   9.208 +     * @return the value of the indexed component in the specified array
   9.209 +     * @exception NullPointerException If the specified object is null
   9.210 +     * @exception IllegalArgumentException If the specified object is not
   9.211 +     * an array, or if the indexed element cannot be converted to the
   9.212 +     * return type by an identity or widening conversion
   9.213 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.214 +     * argument is negative, or if it is greater than or equal to the
   9.215 +     * length of the specified array
   9.216 +     * @see Array#get
   9.217 +     */
   9.218 +    public static native boolean getBoolean(Object array, int index)
   9.219 +        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
   9.220 +
   9.221 +    /**
   9.222 +     * Returns the value of the indexed component in the specified
   9.223 +     * array object, as a {@code byte}.
   9.224 +     *
   9.225 +     * @param array the array
   9.226 +     * @param index the index
   9.227 +     * @return the value of the indexed component in the specified array
   9.228 +     * @exception NullPointerException If the specified object is null
   9.229 +     * @exception IllegalArgumentException If the specified object is not
   9.230 +     * an array, or if the indexed element cannot be converted to the
   9.231 +     * return type by an identity or widening conversion
   9.232 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.233 +     * argument is negative, or if it is greater than or equal to the
   9.234 +     * length of the specified array
   9.235 +     * @see Array#get
   9.236 +     */
   9.237 +    public static byte getByte(Object array, int index)
   9.238 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.239 +        if (array.getClass().getComponentType() != Byte.TYPE) {
   9.240 +            throw new IllegalArgumentException();
   9.241 +        }
   9.242 +        byte[] arr = (byte[]) array;
   9.243 +        return arr[index];
   9.244 +    }
   9.245 +
   9.246 +    /**
   9.247 +     * Returns the value of the indexed component in the specified
   9.248 +     * array object, as a {@code char}.
   9.249 +     *
   9.250 +     * @param array the array
   9.251 +     * @param index the index
   9.252 +     * @return the value of the indexed component in the specified array
   9.253 +     * @exception NullPointerException If the specified object is null
   9.254 +     * @exception IllegalArgumentException If the specified object is not
   9.255 +     * an array, or if the indexed element cannot be converted to the
   9.256 +     * return type by an identity or widening conversion
   9.257 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.258 +     * argument is negative, or if it is greater than or equal to the
   9.259 +     * length of the specified array
   9.260 +     * @see Array#get
   9.261 +     */
   9.262 +    public static native char getChar(Object array, int index)
   9.263 +        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
   9.264 +
   9.265 +    /**
   9.266 +     * Returns the value of the indexed component in the specified
   9.267 +     * array object, as a {@code short}.
   9.268 +     *
   9.269 +     * @param array the array
   9.270 +     * @param index the index
   9.271 +     * @return the value of the indexed component in the specified array
   9.272 +     * @exception NullPointerException If the specified object is null
   9.273 +     * @exception IllegalArgumentException If the specified object is not
   9.274 +     * an array, or if the indexed element cannot be converted to the
   9.275 +     * return type by an identity or widening conversion
   9.276 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.277 +     * argument is negative, or if it is greater than or equal to the
   9.278 +     * length of the specified array
   9.279 +     * @see Array#get
   9.280 +     */
   9.281 +    public static short getShort(Object array, int index)
   9.282 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.283 +        final Class<?> t = array.getClass().getComponentType();
   9.284 +        if (t == Short.TYPE) {
   9.285 +            short[] arr = (short[]) array;
   9.286 +            return arr[index];
   9.287 +        }
   9.288 +        return getByte(array, index);
   9.289 +    }
   9.290 +
   9.291 +    /**
   9.292 +     * Returns the value of the indexed component in the specified
   9.293 +     * array object, as an {@code int}.
   9.294 +     *
   9.295 +     * @param array the array
   9.296 +     * @param index the index
   9.297 +     * @return the value of the indexed component in the specified array
   9.298 +     * @exception NullPointerException If the specified object is null
   9.299 +     * @exception IllegalArgumentException If the specified object is not
   9.300 +     * an array, or if the indexed element cannot be converted to the
   9.301 +     * return type by an identity or widening conversion
   9.302 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.303 +     * argument is negative, or if it is greater than or equal to the
   9.304 +     * length of the specified array
   9.305 +     * @see Array#get
   9.306 +     */
   9.307 +    public static int getInt(Object array, int index) 
   9.308 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.309 +        final Class<?> t = array.getClass().getComponentType();
   9.310 +        if (t == Integer.TYPE) {
   9.311 +            int[] arr = (int[]) array;
   9.312 +            return arr[index];
   9.313 +        }
   9.314 +        return getShort(array, index);
   9.315 +    }
   9.316 +
   9.317 +    /**
   9.318 +     * Returns the value of the indexed component in the specified
   9.319 +     * array object, as a {@code long}.
   9.320 +     *
   9.321 +     * @param array the array
   9.322 +     * @param index the index
   9.323 +     * @return the value of the indexed component in the specified array
   9.324 +     * @exception NullPointerException If the specified object is null
   9.325 +     * @exception IllegalArgumentException If the specified object is not
   9.326 +     * an array, or if the indexed element cannot be converted to the
   9.327 +     * return type by an identity or widening conversion
   9.328 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.329 +     * argument is negative, or if it is greater than or equal to the
   9.330 +     * length of the specified array
   9.331 +     * @see Array#get
   9.332 +     */
   9.333 +    public static long getLong(Object array, int index)
   9.334 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.335 +        final Class<?> t = array.getClass().getComponentType();
   9.336 +        if (t == Long.TYPE) {
   9.337 +            long[] arr = (long[]) array;
   9.338 +            return arr[index];
   9.339 +        }
   9.340 +        return getInt(array, index);
   9.341 +    }
   9.342 +
   9.343 +    /**
   9.344 +     * Returns the value of the indexed component in the specified
   9.345 +     * array object, as a {@code float}.
   9.346 +     *
   9.347 +     * @param array the array
   9.348 +     * @param index the index
   9.349 +     * @return the value of the indexed component in the specified array
   9.350 +     * @exception NullPointerException If the specified object is null
   9.351 +     * @exception IllegalArgumentException If the specified object is not
   9.352 +     * an array, or if the indexed element cannot be converted to the
   9.353 +     * return type by an identity or widening conversion
   9.354 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.355 +     * argument is negative, or if it is greater than or equal to the
   9.356 +     * length of the specified array
   9.357 +     * @see Array#get
   9.358 +     */
   9.359 +    public static float getFloat(Object array, int index)
   9.360 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.361 +        final Class<?> t = array.getClass().getComponentType();
   9.362 +        if (t == Float.TYPE) {
   9.363 +            float[] arr = (float[]) array;
   9.364 +            return arr[index];
   9.365 +        }
   9.366 +        return getLong(array, index);
   9.367 +    }
   9.368 +
   9.369 +    /**
   9.370 +     * Returns the value of the indexed component in the specified
   9.371 +     * array object, as a {@code double}.
   9.372 +     *
   9.373 +     * @param array the array
   9.374 +     * @param index the index
   9.375 +     * @return the value of the indexed component in the specified array
   9.376 +     * @exception NullPointerException If the specified object is null
   9.377 +     * @exception IllegalArgumentException If the specified object is not
   9.378 +     * an array, or if the indexed element cannot be converted to the
   9.379 +     * return type by an identity or widening conversion
   9.380 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.381 +     * argument is negative, or if it is greater than or equal to the
   9.382 +     * length of the specified array
   9.383 +     * @see Array#get
   9.384 +     */
   9.385 +    public static double getDouble(Object array, int index)
   9.386 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.387 +        final Class<?> t = array.getClass().getComponentType();
   9.388 +        if (t == Double.TYPE) {
   9.389 +            double[] arr = (double[]) array;
   9.390 +            return arr[index];
   9.391 +        }
   9.392 +        return getFloat(array, index);
   9.393 +    }
   9.394 +
   9.395 +    /**
   9.396 +     * Sets the value of the indexed component of the specified array
   9.397 +     * object to the specified new value.  The new value is first
   9.398 +     * automatically unwrapped if the array has a primitive component
   9.399 +     * type.
   9.400 +     * @param array the array
   9.401 +     * @param index the index into the array
   9.402 +     * @param value the new value of the indexed component
   9.403 +     * @exception NullPointerException If the specified object argument
   9.404 +     * is null
   9.405 +     * @exception IllegalArgumentException If the specified object argument
   9.406 +     * is not an array, or if the array component type is primitive and
   9.407 +     * an unwrapping conversion fails
   9.408 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.409 +     * argument is negative, or if it is greater than or equal to
   9.410 +     * the length of the specified array
   9.411 +     */
   9.412 +    public static void set(Object array, int index, Object value)
   9.413 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.414 +        if (array.getClass().getComponentType().isPrimitive()) {
   9.415 +            throw new IllegalArgumentException();
   9.416 +        } else {
   9.417 +            Object[] arr = (Object[])array;
   9.418 +            arr[index] = value;
   9.419 +        }
   9.420 +    }
   9.421 +
   9.422 +    /**
   9.423 +     * Sets the value of the indexed component of the specified array
   9.424 +     * object to the specified {@code boolean} value.
   9.425 +     * @param array the array
   9.426 +     * @param index the index into the array
   9.427 +     * @param z the new value of the indexed component
   9.428 +     * @exception NullPointerException If the specified object argument
   9.429 +     * is null
   9.430 +     * @exception IllegalArgumentException If the specified object argument
   9.431 +     * is not an array, or if the specified value cannot be converted
   9.432 +     * to the underlying array's component type by an identity or a
   9.433 +     * primitive widening conversion
   9.434 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.435 +     * argument is negative, or if it is greater than or equal to
   9.436 +     * the length of the specified array
   9.437 +     * @see Array#set
   9.438 +     */
   9.439 +    public static native void setBoolean(Object array, int index, boolean z)
   9.440 +        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
   9.441 +
   9.442 +    /**
   9.443 +     * Sets the value of the indexed component of the specified array
   9.444 +     * object to the specified {@code byte} value.
   9.445 +     * @param array the array
   9.446 +     * @param index the index into the array
   9.447 +     * @param b the new value of the indexed component
   9.448 +     * @exception NullPointerException If the specified object argument
   9.449 +     * is null
   9.450 +     * @exception IllegalArgumentException If the specified object argument
   9.451 +     * is not an array, or if the specified value cannot be converted
   9.452 +     * to the underlying array's component type by an identity or a
   9.453 +     * primitive widening conversion
   9.454 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.455 +     * argument is negative, or if it is greater than or equal to
   9.456 +     * the length of the specified array
   9.457 +     * @see Array#set
   9.458 +     */
   9.459 +    public static void setByte(Object array, int index, byte b)
   9.460 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.461 +        Class<?> t = array.getClass().getComponentType();
   9.462 +        if (t == Byte.TYPE) {
   9.463 +            byte[] arr = (byte[]) array;
   9.464 +            arr[index] = b;
   9.465 +        } else {
   9.466 +            setShort(array, index, b);
   9.467 +        }
   9.468 +    }
   9.469 +
   9.470 +    /**
   9.471 +     * Sets the value of the indexed component of the specified array
   9.472 +     * object to the specified {@code char} value.
   9.473 +     * @param array the array
   9.474 +     * @param index the index into the array
   9.475 +     * @param c the new value of the indexed component
   9.476 +     * @exception NullPointerException If the specified object argument
   9.477 +     * is null
   9.478 +     * @exception IllegalArgumentException If the specified object argument
   9.479 +     * is not an array, or if the specified value cannot be converted
   9.480 +     * to the underlying array's component type by an identity or a
   9.481 +     * primitive widening conversion
   9.482 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.483 +     * argument is negative, or if it is greater than or equal to
   9.484 +     * the length of the specified array
   9.485 +     * @see Array#set
   9.486 +     */
   9.487 +    public static native void setChar(Object array, int index, char c)
   9.488 +        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
   9.489 +
   9.490 +    /**
   9.491 +     * Sets the value of the indexed component of the specified array
   9.492 +     * object to the specified {@code short} value.
   9.493 +     * @param array the array
   9.494 +     * @param index the index into the array
   9.495 +     * @param s the new value of the indexed component
   9.496 +     * @exception NullPointerException If the specified object argument
   9.497 +     * is null
   9.498 +     * @exception IllegalArgumentException If the specified object argument
   9.499 +     * is not an array, or if the specified value cannot be converted
   9.500 +     * to the underlying array's component type by an identity or a
   9.501 +     * primitive widening conversion
   9.502 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.503 +     * argument is negative, or if it is greater than or equal to
   9.504 +     * the length of the specified array
   9.505 +     * @see Array#set
   9.506 +     */
   9.507 +    public static void setShort(Object array, int index, short s)
   9.508 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.509 +        Class<?> t = array.getClass().getComponentType();
   9.510 +        if (t == Short.TYPE) {
   9.511 +            short[] arr = (short[]) array;
   9.512 +            arr[index] = s;
   9.513 +        } else {
   9.514 +            setInt(array, index, s);
   9.515 +        }
   9.516 +        
   9.517 +    }
   9.518 +
   9.519 +    /**
   9.520 +     * Sets the value of the indexed component of the specified array
   9.521 +     * object to the specified {@code int} value.
   9.522 +     * @param array the array
   9.523 +     * @param index the index into the array
   9.524 +     * @param i the new value of the indexed component
   9.525 +     * @exception NullPointerException If the specified object argument
   9.526 +     * is null
   9.527 +     * @exception IllegalArgumentException If the specified object argument
   9.528 +     * is not an array, or if the specified value cannot be converted
   9.529 +     * to the underlying array's component type by an identity or a
   9.530 +     * primitive widening conversion
   9.531 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.532 +     * argument is negative, or if it is greater than or equal to
   9.533 +     * the length of the specified array
   9.534 +     * @see Array#set
   9.535 +     */
   9.536 +    public static void setInt(Object array, int index, int i)
   9.537 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.538 +        Class<?> t = array.getClass().getComponentType();
   9.539 +        if (t == Integer.TYPE) {
   9.540 +            long[] arr = (long[]) array;
   9.541 +            arr[index] = i;
   9.542 +        } else {
   9.543 +            setLong(array, index, i);
   9.544 +        }
   9.545 +    }
   9.546 +
   9.547 +    /**
   9.548 +     * Sets the value of the indexed component of the specified array
   9.549 +     * object to the specified {@code long} value.
   9.550 +     * @param array the array
   9.551 +     * @param index the index into the array
   9.552 +     * @param l the new value of the indexed component
   9.553 +     * @exception NullPointerException If the specified object argument
   9.554 +     * is null
   9.555 +     * @exception IllegalArgumentException If the specified object argument
   9.556 +     * is not an array, or if the specified value cannot be converted
   9.557 +     * to the underlying array's component type by an identity or a
   9.558 +     * primitive widening conversion
   9.559 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.560 +     * argument is negative, or if it is greater than or equal to
   9.561 +     * the length of the specified array
   9.562 +     * @see Array#set
   9.563 +     */
   9.564 +    public static void setLong(Object array, int index, long l)
   9.565 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.566 +        Class<?> t = array.getClass().getComponentType();
   9.567 +        if (t == Long.TYPE) {
   9.568 +            long[] arr = (long[]) array;
   9.569 +            arr[index] = l;
   9.570 +        } else {
   9.571 +            setFloat(array, index, l);
   9.572 +        }
   9.573 +    }
   9.574 +
   9.575 +    /**
   9.576 +     * Sets the value of the indexed component of the specified array
   9.577 +     * object to the specified {@code float} value.
   9.578 +     * @param array the array
   9.579 +     * @param index the index into the array
   9.580 +     * @param f the new value of the indexed component
   9.581 +     * @exception NullPointerException If the specified object argument
   9.582 +     * is null
   9.583 +     * @exception IllegalArgumentException If the specified object argument
   9.584 +     * is not an array, or if the specified value cannot be converted
   9.585 +     * to the underlying array's component type by an identity or a
   9.586 +     * primitive widening conversion
   9.587 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.588 +     * argument is negative, or if it is greater than or equal to
   9.589 +     * the length of the specified array
   9.590 +     * @see Array#set
   9.591 +     */
   9.592 +    public static void setFloat(Object array, int index, float f)
   9.593 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.594 +        Class<?> t = array.getClass().getComponentType();
   9.595 +        if (t == Float.TYPE) {
   9.596 +            float[] arr = (float[])array;
   9.597 +            arr[index] = f;
   9.598 +        } else {
   9.599 +            setDouble(array, index, f);
   9.600 +        }
   9.601 +    }
   9.602 +
   9.603 +    /**
   9.604 +     * Sets the value of the indexed component of the specified array
   9.605 +     * object to the specified {@code double} value.
   9.606 +     * @param array the array
   9.607 +     * @param index the index into the array
   9.608 +     * @param d the new value of the indexed component
   9.609 +     * @exception NullPointerException If the specified object argument
   9.610 +     * is null
   9.611 +     * @exception IllegalArgumentException If the specified object argument
   9.612 +     * is not an array, or if the specified value cannot be converted
   9.613 +     * to the underlying array's component type by an identity or a
   9.614 +     * primitive widening conversion
   9.615 +     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
   9.616 +     * argument is negative, or if it is greater than or equal to
   9.617 +     * the length of the specified array
   9.618 +     * @see Array#set
   9.619 +     */
   9.620 +    public static void setDouble(Object array, int index, double d)
   9.621 +    throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
   9.622 +        Class<?> t = array.getClass().getComponentType();
   9.623 +        if (t == Double.TYPE) {
   9.624 +            double[] arr = (double[])array;
   9.625 +            arr[index] = d;
   9.626 +        } else {
   9.627 +            throw new IllegalArgumentException("argument type mismatch");
   9.628 +        }
   9.629 +    }
   9.630 +
   9.631 +    /*
   9.632 +     * Private
   9.633 +     */
   9.634 +
   9.635 +    @JavaScriptBody(args = { "primitive", "sig", "length" }, body =
   9.636 +          "var arr = new Array(length);\n"
   9.637 +        + "var value = primitive ? 0 : null;\n"
   9.638 +        + "for(var i = 0; i < length; i++) arr[i] = value;\n"
   9.639 +        + "arr.jvmName = sig;\n"
   9.640 +        + "return arr;"
   9.641 +    )
   9.642 +    private static native Object newArray(boolean primitive, String sig, int length);
   9.643 +
   9.644 +    private static Object multiNewArray(String sig, int[] dims, int index)
   9.645 +    throws IllegalArgumentException, NegativeArraySizeException {
   9.646 +        if (dims.length == index + 1) {
   9.647 +            return newArray(sig.length() == 2, sig, dims[index]);
   9.648 +        }
   9.649 +        Object[] arr = (Object[]) newArray(false, sig, dims[index]);
   9.650 +        String compsig = sig.substring(1);
   9.651 +        for (int i = 0; i < arr.length; i++) {
   9.652 +            arr[i] = multiNewArray(compsig, dims, index + 1);
   9.653 +        }
   9.654 +        return arr;
   9.655 +    }
   9.656 +    private static Object fromPrimitive(Class<?> t, Object array, int index) {
   9.657 +        return Method.fromPrimitive(t, atArray(array, index));
   9.658 +    }
   9.659 +    
   9.660 +    @JavaScriptBody(args = { "array", "index" }, body = "return array[index]")
   9.661 +    private static native Object atArray(Object array, int index);
   9.662 +}
    10.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Tue Jan 15 11:39:15 2013 +0100
    10.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Mon Jan 21 15:57:01 2013 +0100
    10.3 @@ -537,7 +537,7 @@
    10.4      )
    10.5      private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
    10.6  
    10.7 -    private static Object fromPrimitive(Class<?> type, Object o) {
    10.8 +    static Object fromPrimitive(Class<?> type, Object o) {
    10.9          if (type == Integer.TYPE) {
   10.10              return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
   10.11          }
   10.12 @@ -559,6 +559,9 @@
   10.13          if (type == Short.TYPE) {
   10.14              return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
   10.15          }
   10.16 +        if (type == Character.TYPE) {
   10.17 +            return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o);
   10.18 +        }
   10.19          if (type.getName().equals("void")) {
   10.20              return null;
   10.21          }
   10.22 @@ -592,6 +595,9 @@
   10.23          if (type == Short.TYPE) {
   10.24              return toRaw("shortValue__S", o);
   10.25          }
   10.26 +        if (type == Character.TYPE) {
   10.27 +            return toRaw("charValue__C", o);
   10.28 +        }
   10.29          if (type.getName().equals("void")) {
   10.30              return o;
   10.31          }
   10.32 @@ -640,10 +646,10 @@
   10.33          return Modifier.isSynthetic(getModifiers());
   10.34      }
   10.35  
   10.36 -    @JavaScriptBody(args = { "self", "ac" }, 
   10.37 +    @JavaScriptBody(args = { "ac" }, 
   10.38          body = 
   10.39 -          "if (self.fld_data.anno) {"
   10.40 -        + "  return self.fld_data.anno['L' + ac.jvmName + ';'];"
   10.41 +          "if (this.fld_data.anno) {"
   10.42 +        + "  return this.fld_data.anno['L' + ac.jvmName + ';'];"
   10.43          + "} else return null;"
   10.44      )
   10.45      private Object getAnnotationData(Class<?> annotationClass) {
    11.1 --- a/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java	Tue Jan 15 11:39:15 2013 +0100
    11.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java	Mon Jan 21 15:57:01 2013 +0100
    11.3 @@ -144,6 +144,8 @@
    11.4                          return Short.TYPE;
    11.5                      case 'V':
    11.6                          return Void.TYPE;
    11.7 +                    case 'C':
    11.8 +                        return Character.TYPE;
    11.9                      case 'L':
   11.10                          try {
   11.11                              int up = sig.indexOf("_2");
    12.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Tue Jan 15 11:39:15 2013 +0100
    12.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Mon Jan 21 15:57:01 2013 +0100
    12.3 @@ -1,10 +1,20 @@
    12.4 -// initialize methods on String constants
    12.5 +// initialize methods on arrays and String constants
    12.6 +vm.java_lang_reflect_Array(false);
    12.7  vm.java_lang_String(false);
    12.8  
    12.9 -// we need initialized arrays
   12.10 -Array.prototype.fillWith = function(value) {
   12.11 -  for(var i = 0; i < this.length; i++) this[i] = value;
   12.12 -  return this;
   12.13 +Array.prototype.at = function(indx, value) {
   12.14 +  if (indx < 0 || indx > this.length) {
   12.15 +      var e = vm.java_lang_ArrayIndexOutOfBoundsException(true);
   12.16 +      e.constructor.cons__VLjava_lang_String_2.call(e, indx.toString());
   12.17 +      throw e;
   12.18 +  }
   12.19 +  if (arguments.length === 2) {
   12.20 +      this[indx] = value;
   12.21 +  }
   12.22 +  return this[indx];
   12.23 +};
   12.24 +Array.prototype.getClass__Ljava_lang_Class_2 = function() {
   12.25 +  return vm.java_lang_Class(false).defineArray__Ljava_lang_Class_2Ljava_lang_String_2(this.jvmName);
   12.26  };
   12.27  Array.prototype.clone__Ljava_lang_Object_2 = function() {
   12.28    var s = this.length;
    13.1 --- a/javap/src/main/java/org/apidesign/javap/StackMapIterator.java	Tue Jan 15 11:39:15 2013 +0100
    13.2 +++ b/javap/src/main/java/org/apidesign/javap/StackMapIterator.java	Mon Jan 21 15:57:01 2013 +0100
    13.3 @@ -123,7 +123,7 @@
    13.4          }
    13.5  
    13.6          final int length = methodSignature.length();
    13.7 -        int skipType = 0;
    13.8 +        boolean skipType = false;
    13.9          int argType;
   13.10          for (int i = 1; i < length; ++i) {
   13.11              switch (methodSignature.charAt(i)) {
   13.12 @@ -156,10 +156,10 @@
   13.13                      // not interested in the return value type
   13.14                      return argTypes;
   13.15                  case '[':
   13.16 -                    if (skipType == 0) {
   13.17 +                    if (!skipType) {
   13.18                          argTypes.add(ITEM_Object);
   13.19 +                        skipType = true;
   13.20                      }
   13.21 -                    ++skipType;
   13.22                      continue;
   13.23  
   13.24                  default:
   13.25 @@ -167,10 +167,10 @@
   13.26                                    "Invalid method signature");
   13.27              }
   13.28  
   13.29 -            if (skipType == 0) {
   13.30 +            if (!skipType) {
   13.31                  argTypes.add(argType);
   13.32              } else {
   13.33 -                --skipType;
   13.34 +                skipType = false;
   13.35              }
   13.36          }
   13.37  
    14.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java	Tue Jan 15 11:39:15 2013 +0100
    14.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java	Mon Jan 21 15:57:01 2013 +0100
    14.3 @@ -37,8 +37,8 @@
    14.4      void add(Object objectType) {
    14.5          addElement(objectType);
    14.6      }
    14.7 -    @JavaScriptBody(args = { "self", "obj" }, body = 
    14.8 -        "self.push(obj);"
    14.9 +    @JavaScriptBody(args = { "obj" }, body = 
   14.10 +        "this.push(obj);"
   14.11      )
   14.12      void addElement(Object obj) {
   14.13          final int s = size();
   14.14 @@ -46,16 +46,16 @@
   14.15          setElementAt(obj, s);
   14.16      }
   14.17  
   14.18 -    @JavaScriptBody(args = { "self" }, body = 
   14.19 -        "return self.length;"
   14.20 +    @JavaScriptBody(args = { }, body = 
   14.21 +        "return this.length;"
   14.22      )
   14.23      int size() {
   14.24          return arr == null ? 0 : arr.length;
   14.25      }
   14.26  
   14.27 -    @JavaScriptBody(args = { "self", "newArr" }, body =
   14.28 -        "for (var i = 0; i < self.length; i++) {\n"
   14.29 -      + "  newArr[i] = self[i];\n"
   14.30 +    @JavaScriptBody(args = { "newArr" }, body =
   14.31 +        "for (var i = 0; i < this.length; i++) {\n"
   14.32 +      + "  newArr[i] = this[i];\n"
   14.33        + "}\n")
   14.34      void copyInto(Object[] newArr) {
   14.35          if (arr == null) {
   14.36 @@ -67,8 +67,8 @@
   14.37          }
   14.38      }
   14.39  
   14.40 -    @JavaScriptBody(args = { "self", "index" }, body =
   14.41 -        "return self[index];"
   14.42 +    @JavaScriptBody(args = { "index" }, body =
   14.43 +        "return this[index];"
   14.44      )
   14.45      Object elementAt(int index) {
   14.46          return arr[index];
   14.47 @@ -80,8 +80,8 @@
   14.48          arr = newArr;
   14.49      }
   14.50  
   14.51 -    @JavaScriptBody(args = { "self", "val", "index" }, body = 
   14.52 -        "self[index] = val;"
   14.53 +    @JavaScriptBody(args = { "val", "index" }, body = 
   14.54 +        "this[index] = val;"
   14.55      )
   14.56      void setElementAt(Object val, int index) {
   14.57          arr[index] = val;
    15.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Tue Jan 15 11:39:15 2013 +0100
    15.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Mon Jan 21 15:57:01 2013 +0100
    15.3 @@ -43,7 +43,7 @@
    15.4  import javax.tools.Diagnostic;
    15.5  import javax.tools.FileObject;
    15.6  import javax.tools.StandardLocation;
    15.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    15.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    15.9  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   15.10  import org.openide.util.lookup.ServiceProvider;
   15.11  
   15.12 @@ -55,7 +55,7 @@
   15.13  @ServiceProvider(service=Processor.class)
   15.14  @SupportedAnnotationTypes({
   15.15      "org.apidesign.bck2brwsr.htmlpage.api.Page",
   15.16 -    "org.apidesign.bck2brwsr.htmlpage.api.OnClick"
   15.17 +    "org.apidesign.bck2brwsr.htmlpage.api.On"
   15.18  })
   15.19  public final class PageProcessor extends AbstractProcessor {
   15.20      @Override
   15.21 @@ -95,7 +95,7 @@
   15.22                              append(type).append("(\"").append(id).append("\");\n");
   15.23                      }
   15.24                      w.append("  static {\n");
   15.25 -                    if (!initializeOnClick(pe, w, pp)) {
   15.26 +                    if (!initializeOnClick((TypeElement) e, w, pp)) {
   15.27                          return false;
   15.28                      }
   15.29                      w.append("  }\n");
   15.30 @@ -138,19 +138,18 @@
   15.31          return id.toUpperCase(Locale.ENGLISH).replace('.', '_');
   15.32      }
   15.33  
   15.34 -    private boolean initializeOnClick(PackageElement pe, Writer w, ProcessPage pp) throws IOException {
   15.35 +    private boolean initializeOnClick(TypeElement type, Writer w, ProcessPage pp) throws IOException {
   15.36          TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType();
   15.37 -        for (Element clazz : pe.getEnclosedElements()) {
   15.38 -            if (clazz.getKind() != ElementKind.CLASS) {
   15.39 -                continue;
   15.40 -            }
   15.41 -            TypeElement type = (TypeElement)clazz;
   15.42 -            for (Element method : clazz.getEnclosedElements()) {
   15.43 -                OnClick oc = method.getAnnotation(OnClick.class);
   15.44 +        { //for (Element clazz : pe.getEnclosedElements()) {
   15.45 +          //  if (clazz.getKind() != ElementKind.CLASS) {
   15.46 +            //    continue;
   15.47 +           // }
   15.48 +            for (Element method : type.getEnclosedElements()) {
   15.49 +                On oc = method.getAnnotation(On.class);
   15.50                  if (oc != null) {
   15.51                      for (String id : oc.id()) {
   15.52                          if (pp.tagNameForId(id) == null) {
   15.53 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
   15.54 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + id + " does not exist in the HTML page. Found only " + pp.ids(), method);
   15.55                              return false;
   15.56                          }
   15.57                          ExecutableElement ee = (ExecutableElement)method;
   15.58 @@ -159,21 +158,21 @@
   15.59                              hasParam = false;
   15.60                          } else {
   15.61                              if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
   15.62 -                                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
   15.63 +                                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method should either have no arguments or one String argument", ee);
   15.64                                  return false;
   15.65                              }
   15.66                              hasParam = true;
   15.67                          }
   15.68                          if (!ee.getModifiers().contains(Modifier.STATIC)) {
   15.69 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
   15.70 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method has to be static", ee);
   15.71                              return false;
   15.72                          }
   15.73                          if (ee.getModifiers().contains(Modifier.PRIVATE)) {
   15.74 -                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
   15.75 +                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method can't be private", ee);
   15.76                              return false;
   15.77                          }
   15.78 -                        w.append("  ").append(cnstnt(id)).
   15.79 -                            append(".addOnClick(new Runnable() { public void run() {\n");
   15.80 +                        w.append("  OnEvent." + oc.event()).append(".of(").append(cnstnt(id)).
   15.81 +                            append(").perform(new Runnable() { public void run() {\n");
   15.82                          w.append("    ").append(type.getSimpleName().toString()).
   15.83                              append('.').append(ee.getSimpleName()).append("(");
   15.84                          if (hasParam) {
    16.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Tue Jan 15 11:39:15 2013 +0100
    16.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Mon Jan 21 15:57:01 2013 +0100
    16.3 @@ -37,29 +37,45 @@
    16.4          body="var e = window.document.getElementById(el.fld_id);\n"
    16.5             + "e[property] = value;\n"
    16.6      )
    16.7 -    static void setAttribute(Element el, String property, Object value) {
    16.8 -        throw new UnsupportedOperationException("Needs JavaScript!");
    16.9 -    }
   16.10 +    static native void setAttribute(Element el, String property, Object value);
   16.11  
   16.12      @JavaScriptBody(
   16.13          args={"el", "property"},
   16.14          body="var e = window.document.getElementById(el.fld_id);\n"
   16.15             + "return e[property];\n"
   16.16      )
   16.17 -    static Object getAttribute(Element el, String property) {
   16.18 -        throw new UnsupportedOperationException("Needs JavaScript!");
   16.19 -    }
   16.20 +    static native Object getAttribute(Element el, String property);
   16.21      
   16.22      /** Executes given runnable when user performs a "click" on the given
   16.23       * element.
   16.24       * @param r the runnable to execute, never null
   16.25       */
   16.26      @JavaScriptBody(
   16.27 -        args={"el", "r"},
   16.28 -        body="var e = window.document.getElementById(el.fld_id);\n"
   16.29 -           + "e.onclick = function() { r.run__V(); };\n"
   16.30 +        args={ "ev", "r" },
   16.31 +        body="var e = window.document.getElementById(this.fld_id);\n"
   16.32 +           + "e[ev.fld_id] = function() { r.run__V(); };\n"
   16.33      )
   16.34 -    public final void addOnClick(Runnable r) {
   16.35 -        throw new UnsupportedOperationException("Needs JavaScript!");
   16.36 +    final native void on(OnEvent ev, Runnable r);
   16.37 +
   16.38 +    /** Shows alert message dialog in a browser.
   16.39 +     * @param msg the message to show
   16.40 +     */
   16.41 +    @JavaScriptBody(args = "msg", body = "alert(msg);")
   16.42 +    public static native void alert(String msg);
   16.43 +
   16.44 +    /** Generic way to query any attribute of this element.
   16.45 +     * @param property name of the attribute
   16.46 +     */
   16.47 +    public final Object getAttribute(String property) {
   16.48 +        return getAttribute(this, property);
   16.49 +    }
   16.50 +    
   16.51 +    /** Generic way to change an attribute of this element.
   16.52 +     * 
   16.53 +     * @param property name of the attribute
   16.54 +     * @param value value to associate with the attribute
   16.55 +     */
   16.56 +    public final void setAttribute(String property, Object value) {
   16.57 +        setAttribute(this, property, value);
   16.58      }
   16.59  }
    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/On.java	Mon Jan 21 15:57:01 2013 +0100
    17.3 @@ -0,0 +1,35 @@
    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 +import java.lang.annotation.ElementType;
   17.24 +import java.lang.annotation.Retention;
   17.25 +import java.lang.annotation.RetentionPolicy;
   17.26 +import java.lang.annotation.Target;
   17.27 +
   17.28 +/** Adds an onClick handler to an element identified by given <em>id</em>.
   17.29 + * Apply on a <code>public static void</code> method with no arguments.
   17.30 + *
   17.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   17.32 + */
   17.33 +@Retention(RetentionPolicy.SOURCE)
   17.34 +@Target(ElementType.METHOD)
   17.35 +public @interface On {
   17.36 +    OnEvent event();
   17.37 +    String[] id();
   17.38 +}
    18.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java	Tue Jan 15 11:39:15 2013 +0100
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,34 +0,0 @@
    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 -import java.lang.annotation.ElementType;
   18.24 -import java.lang.annotation.Retention;
   18.25 -import java.lang.annotation.RetentionPolicy;
   18.26 -import java.lang.annotation.Target;
   18.27 -
   18.28 -/** Adds an onClick handler to an element identified by given <em>id</em>.
   18.29 - * Apply on a <code>public static void</code> method with no arguments.
   18.30 - *
   18.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   18.32 - */
   18.33 -@Retention(RetentionPolicy.SOURCE)
   18.34 -@Target(ElementType.METHOD)
   18.35 -public @interface OnClick {
   18.36 -    String[] id();
   18.37 -}
    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/OnController.java	Mon Jan 21 15:57:01 2013 +0100
    19.3 @@ -0,0 +1,43 @@
    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 +/** Controller created via {@link OnEvent#of(org.apidesign.bck2brwsr.htmlpage.api.Element[])}.
   19.24 + *
   19.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   19.26 + */
   19.27 +public final class OnController {
   19.28 +    private final Element[] arr;
   19.29 +    private final OnEvent event;
   19.30 +    
   19.31 +    OnController(OnEvent event, Element[] arr) {
   19.32 +        this.event = event;
   19.33 +        this.arr = arr;
   19.34 +    }
   19.35 +    
   19.36 +    /** Registers a runnable to be performed on associated {@link OnEvent} 
   19.37 +     * and {@link Element}.
   19.38 +     * 
   19.39 +     * @see OnEvent#of
   19.40 +     */
   19.41 +    public void perform(Runnable r) {
   19.42 +        for (Element e : arr) {
   19.43 +            e.on(event, r);
   19.44 +        }
   19.45 +    }
   19.46 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnEvent.java	Mon Jan 21 15:57:01 2013 +0100
    20.3 @@ -0,0 +1,95 @@
    20.4 +/**
    20.5 + * Back 2 Browser Bytecode Translator
    20.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    20.7 + *
    20.8 + * This program is free software: you can redistribute it and/or modify
    20.9 + * it under the terms of the GNU General Public License as published by
   20.10 + * the Free Software Foundation, version 2 of the License.
   20.11 + *
   20.12 + * This program is distributed in the hope that it will be useful,
   20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.15 + * GNU General Public License for more details.
   20.16 + *
   20.17 + * You should have received a copy of the GNU General Public License
   20.18 + * along with this program. Look for COPYING file in the top folder.
   20.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   20.20 + */
   20.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   20.22 +
   20.23 +/** Type of events to use in connection with {@link On} annotation.
   20.24 + *
   20.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   20.26 + */
   20.27 +public enum OnEvent {
   20.28 +    ABORT("onabort"),
   20.29 +    BLUR("onblur"),
   20.30 +    CAN_PLAY("oncanplay"),
   20.31 +    CAN_PLAY_THROUGH("oncanplaythrough"),
   20.32 +    CLICK("onclick"),
   20.33 +    CONTEXT_MENU("oncontextmenu"),
   20.34 +    DBL_CLICK("ondblclick"),
   20.35 +    DRAG("ondrag"),
   20.36 +    DRAG_END("ondragend"),
   20.37 +    DRAG_ENTER("ondragenter"),
   20.38 +    DRAG_LEAVE("ondragleave"),
   20.39 +    DRAG_OVER("ondragover"),
   20.40 +    DRAG_START("ondragstart"),
   20.41 +    DROP("ondrop"),
   20.42 +    DURATION_CHANGE("ondurationchange"),
   20.43 +    EMPTIED("onemptied"),
   20.44 +    ENDED("onended"),
   20.45 +    ERROR("onerror"),
   20.46 +    FOCUS("onfocus"),
   20.47 +    FORM_CHANGE("onformchange"),
   20.48 +    FORM_INPUT("onforminput"),
   20.49 +    INPUT("oninput"),
   20.50 +    INVALID("oninvalid"),
   20.51 +    KEY_DOWN("onkeydown"),
   20.52 +    KEY_PRESS("onkeypress"),
   20.53 +    KEY_UP("onkeyup"),
   20.54 +    LOAD("onload"),
   20.55 +    LOADED_DATA("onloadeddata"),
   20.56 +    LOADED_META_DATA("onloadedmetadata"),
   20.57 +    LOAD_START("onloadstart"),
   20.58 +    MOUSE_DOWN("onmousedown"),
   20.59 +    MOUSE_MOVE("onmousemove"),
   20.60 +    MOUSE_OUT("onmouseout"),
   20.61 +    MOUSE_OVER("onmouseover"),
   20.62 +    MOUSE_UP("onmouseup"),
   20.63 +    MOUSE_WHEEL("onmousewheel"),
   20.64 +    PAUSE("onpause"),
   20.65 +    PLAY("onplay"),
   20.66 +    PLAYING("onplaying"),
   20.67 +    PROGRESS("onprogress"),
   20.68 +    RATE_CHANGE("onratechange"),
   20.69 +    READY_STATE_CHANGE("onreadystatechange"),
   20.70 +    SCROLL("onscroll"),
   20.71 +    SEEKED("onseeked"),
   20.72 +    SEEKING("onseeking"),
   20.73 +    SELECT("onselect"),
   20.74 +    SHOW("onshow"),
   20.75 +    STALLED("onstalled"),
   20.76 +    SUBMIT("onsubmit"),
   20.77 +    SUSPEND("onsuspend"),
   20.78 +    TIME_UPDATE("ontimeupdate"),
   20.79 +    VOLUME_CHANGE("onvolumechange"),
   20.80 +    WAITING("onwaiting");
   20.81 +    
   20.82 +    final String id;
   20.83 +    
   20.84 +    private OnEvent(String id) {
   20.85 +        this.id = id;
   20.86 +    }
   20.87 +    
   20.88 +    /** What should happen when this even happen on one
   20.89 +     * of associated elements. Continue by calling {@link OnController#perform(java.lang.Runnable)}
   20.90 +     * method.
   20.91 +     * 
   20.92 +     * @param elmnts one or more elements
   20.93 +     * @return controller with <code>perform</code> method.
   20.94 +     */
   20.95 +    public OnController of(Element... elmnts) {
   20.96 +        return new OnController(this, elmnts);
   20.97 +    }
   20.98 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Timer.java	Mon Jan 21 15:57:01 2013 +0100
    21.3 @@ -0,0 +1,59 @@
    21.4 +/**
    21.5 + * Back 2 Browser Bytecode Translator
    21.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    21.7 + *
    21.8 + * This program is free software: you can redistribute it and/or modify
    21.9 + * it under the terms of the GNU General Public License as published by
   21.10 + * the Free Software Foundation, version 2 of the License.
   21.11 + *
   21.12 + * This program is distributed in the hope that it will be useful,
   21.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.15 + * GNU General Public License for more details.
   21.16 + *
   21.17 + * You should have received a copy of the GNU General Public License
   21.18 + * along with this program. Look for COPYING file in the top folder.
   21.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   21.20 + */
   21.21 +package org.apidesign.bck2brwsr.htmlpage.api;
   21.22 +
   21.23 +import java.io.Closeable;
   21.24 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   21.25 +
   21.26 +/**
   21.27 + *
   21.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   21.29 + */
   21.30 +public class Timer implements Closeable {
   21.31 +    private final Object t;
   21.32 +    
   21.33 +    private Timer(Object t) {
   21.34 +        this.t = t;
   21.35 +    }
   21.36 +    
   21.37 +    /** Creates a timer that invokes provided runnable on a fixed interval
   21.38 +     * 
   21.39 +     * @param r the runnable to execute
   21.40 +     * @param time milliseconds to invoke the timer periodically
   21.41 +     */
   21.42 +    public static Timer create(Runnable r, int time) {
   21.43 +        return new Timer(interval(r, time));
   21.44 +    }
   21.45 +    
   21.46 +    @JavaScriptBody(args = { "r", "time" }, body = 
   21.47 +        "return window.setInterval(function() { r.run__V(); }, time);"
   21.48 +    )
   21.49 +    private static native Object interval(Runnable r, int time);
   21.50 +
   21.51 +    @JavaScriptBody(args = { "self" }, body = 
   21.52 +        "window.clearInterval(self);"
   21.53 +    )
   21.54 +    private static native void close(Object self);
   21.55 +    
   21.56 +    /** Cancels this timer.
   21.57 +     */
   21.58 +    @Override
   21.59 +    public void close() {
   21.60 +        close(t);
   21.61 +    }
   21.62 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ModelTest.java	Mon Jan 21 15:57:01 2013 +0100
    22.3 @@ -0,0 +1,34 @@
    22.4 +/**
    22.5 + * Back 2 Browser Bytecode Translator
    22.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    22.7 + *
    22.8 + * This program is free software: you can redistribute it and/or modify
    22.9 + * it under the terms of the GNU General Public License as published by
   22.10 + * the Free Software Foundation, version 2 of the License.
   22.11 + *
   22.12 + * This program is distributed in the hope that it will be useful,
   22.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.15 + * GNU General Public License for more details.
   22.16 + *
   22.17 + * You should have received a copy of the GNU General Public License
   22.18 + * along with this program. Look for COPYING file in the top folder.
   22.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   22.20 + */
   22.21 +package org.apidesign.bck2brwsr.htmlpage;
   22.22 +
   22.23 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
   22.24 +import static org.testng.Assert.*;
   22.25 +import org.testng.annotations.Test;
   22.26 +
   22.27 +/**
   22.28 + *
   22.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   22.30 + */
   22.31 +@Page(xhtml = "Empty.html", className = "Model")
   22.32 +public class ModelTest {
   22.33 +    @Test public void classGenerated() {
   22.34 +        Class<?> c = Model.class;
   22.35 +        assertNotNull(c, "Class for empty page generated");
   22.36 +    }
   22.37 +}
    23.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java	Tue Jan 15 11:39:15 2013 +0100
    23.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java	Mon Jan 21 15:57:01 2013 +0100
    23.3 @@ -17,7 +17,8 @@
    23.4   */
    23.5  package org.apidesign.bck2brwsr.htmlpage;
    23.6  
    23.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    23.8 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
    23.9 +import org.apidesign.bck2brwsr.htmlpage.api.On;
   23.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   23.11  
   23.12  /** Trivial demo for the bck2brwsr project. First of all start
   23.13 @@ -42,12 +43,12 @@
   23.14   */
   23.15  @Page(xhtml="TestPage.html")
   23.16  public class PageController {
   23.17 -    @OnClick(id="pg.button")
   23.18 +    @On(event = CLICK, id="pg.button")
   23.19      static void updateTitle() {
   23.20          TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
   23.21      }
   23.22      
   23.23 -    @OnClick(id={ "pg.title", "pg.text" })
   23.24 +    @On(event = CLICK, id={ "pg.title", "pg.text" })
   23.25      static void click(String id) {
   23.26          if (!id.equals("pg.title")) {
   23.27              throw new IllegalStateException();
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/javaquery/api/src/test/resources/org/apidesign/bck2brwsr/htmlpage/Empty.html	Mon Jan 21 15:57:01 2013 +0100
    24.3 @@ -0,0 +1,29 @@
    24.4 +<?xml version="1.0" encoding="UTF-8"?>
    24.5 +<!--
    24.6 +
    24.7 +    Back 2 Browser Bytecode Translator
    24.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    24.9 +
   24.10 +    This program is free software: you can redistribute it and/or modify
   24.11 +    it under the terms of the GNU General Public License as published by
   24.12 +    the Free Software Foundation, version 2 of the License.
   24.13 +
   24.14 +    This program is distributed in the hope that it will be useful,
   24.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.17 +    GNU General Public License for more details.
   24.18 +
   24.19 +    You should have received a copy of the GNU General Public License
   24.20 +    along with this program. Look for COPYING file in the top folder.
   24.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   24.22 +
   24.23 +-->
   24.24 +<!DOCTYPE html>
   24.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   24.26 +    <head>
   24.27 +        <title>Empty</title>
   24.28 +    </head>
   24.29 +    <body>
   24.30 +        Empty page
   24.31 +    </body>
   24.32 +</html>
    25.1 --- a/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Tue Jan 15 11:39:15 2013 +0100
    25.2 +++ b/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Mon Jan 21 15:57:01 2013 +0100
    25.3 @@ -17,7 +17,8 @@
    25.4   */
    25.5  package org.apidesign.bck2brwsr.mavenhtml;
    25.6  
    25.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    25.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    25.9 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
   25.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   25.11  
   25.12  /** HTML5 & Java demo showing the power of 
   25.13 @@ -31,21 +32,21 @@
   25.14      private static double memory;
   25.15      private static String operation;
   25.16      
   25.17 -    @OnClick(id="clear")
   25.18 +    @On(event = CLICK, id="clear")
   25.19      static void clear() {
   25.20          memory = 0;
   25.21          operation = null;
   25.22          Calculator.DISPLAY.setValue("0");
   25.23      }
   25.24      
   25.25 -    @OnClick(id= { "plus", "minus", "mul", "div" })
   25.26 +    @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
   25.27      static void applyOp(String op) {
   25.28          memory = getValue();
   25.29          operation = op;
   25.30          Calculator.DISPLAY.setValue("0");
   25.31      }
   25.32      
   25.33 -    @OnClick(id="result")
   25.34 +    @On(event = CLICK, id="result")
   25.35      static void computeTheValue() {
   25.36          switch (operation) {
   25.37              case "plus": setValue(memory + getValue()); break;
   25.38 @@ -56,7 +57,7 @@
   25.39          }
   25.40      }
   25.41      
   25.42 -    @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   25.43 +    @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   25.44      static void addDigit(String digit) {
   25.45          digit = digit.substring(1);
   25.46          String v = Calculator.DISPLAY.getValue();
    26.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Tue Jan 15 11:39:15 2013 +0100
    26.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Mon Jan 21 15:57:01 2013 +0100
    26.3 @@ -17,7 +17,8 @@
    26.4   */
    26.5  package org.apidesign.bck2brwsr.mavenhtml;
    26.6  
    26.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    26.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
    26.9 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
   26.10  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   26.11  
   26.12  /** HTML5 & Java demo showing the power of 
   26.13 @@ -31,21 +32,21 @@
   26.14      private static double memory;
   26.15      private static String operation;
   26.16      
   26.17 -    @OnClick(id="clear")
   26.18 +    @On(event = CLICK, id="clear")
   26.19      static void clear() {
   26.20          memory = 0;
   26.21          operation = null;
   26.22          Calculator.DISPLAY.setValue("0");
   26.23      }
   26.24      
   26.25 -    @OnClick(id= { "plus", "minus", "mul", "div" })
   26.26 +    @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
   26.27      static void applyOp(String op) {
   26.28          memory = getValue();
   26.29          operation = op;
   26.30          Calculator.DISPLAY.setValue("0");
   26.31      }
   26.32      
   26.33 -    @OnClick(id="result")
   26.34 +    @On(event = CLICK, id="result")
   26.35      static void computeTheValue() {
   26.36          switch (operation) {
   26.37              case "plus": setValue(memory + getValue()); break;
   26.38 @@ -56,7 +57,7 @@
   26.39          }
   26.40      }
   26.41      
   26.42 -    @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   26.43 +    @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   26.44      static void addDigit(String digit) {
   26.45          digit = digit.substring(1);
   26.46          String v = Calculator.DISPLAY.getValue();
    27.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Tue Jan 15 11:39:15 2013 +0100
    27.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Mon Jan 21 15:57:01 2013 +0100
    27.3 @@ -237,20 +237,14 @@
    27.4          
    27.5          URI uri = new URI("http://localhost:" + port + page);
    27.6          LOG.log(Level.INFO, "Showing {0}", uri);
    27.7 -//        try {
    27.8 -//            Desktop.getDesktop().browse(uri);
    27.9 -//            return null;
   27.10 -//        } catch (UnsupportedOperationException ex)
   27.11 -        {
   27.12 -//            File dir = File.createTempFile("chrome", ".dir");
   27.13 -//            dir.delete();
   27.14 -//            dir.mkdirs();
   27.15 -//            String[] cmd = { 
   27.16 -//                "google-chrome", "--user-data-dir=" + dir, "--app=" + uri.toString()
   27.17 -//            };
   27.18 -//            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
   27.19 -//            final Process process = Runtime.getRuntime().exec(cmd);
   27.20 -//            return new Object[] { process, dir };
   27.21 +        if (cmd == null) {
   27.22 +            try {
   27.23 +                java.awt.Desktop.getDesktop().browse(uri);
   27.24 +                LOG.log(Level.INFO, "Desktop.browse successfully finished");
   27.25 +                return null;
   27.26 +            } catch (UnsupportedOperationException ex) {
   27.27 +                LOG.log(Level.INFO, "Desktop.browse not supported", ex);
   27.28 +            }
   27.29          }
   27.30          {
   27.31              String cmdName = cmd == null ? "xdg-open" : cmd;
   27.32 @@ -365,8 +359,13 @@
   27.33                      r = r.substring(1);
   27.34                  }
   27.35              }
   27.36 -            if (r.endsWith(".html") || r.endsWith(".xhtml")) {
   27.37 +            if (r.endsWith(".html")) {
   27.38                  response.setContentType("text/html");
   27.39 +                LOG.info("Content type text/html");
   27.40 +            }
   27.41 +            if (r.endsWith(".xhtml")) {
   27.42 +                response.setContentType("application/xhtml+xml");
   27.43 +                LOG.info("Content type application/xhtml+xml");
   27.44              }
   27.45              OutputStream os = response.getOutputStream();
   27.46              try (InputStream is = res.get(r)) {
    28.1 --- a/mojo/src/main/resources/archetype-resources/src/main/java/App.java	Tue Jan 15 11:39:15 2013 +0100
    28.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/java/App.java	Mon Jan 21 15:57:01 2013 +0100
    28.3 @@ -1,6 +1,7 @@
    28.4  package ${package};
    28.5  
    28.6 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    28.7 +import org.apidesign.bck2brwsr.htmlpage.api.*;
    28.8 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
    28.9  import org.apidesign.bck2brwsr.htmlpage.api.Page;
   28.10  
   28.11  /** Edit the index.xhtml file. Use 'id' to name certain HTML elements.
   28.12 @@ -8,8 +9,9 @@
   28.13   */
   28.14  @Page(xhtml="index.xhtml", className="Index")
   28.15  public class App {
   28.16 -    @OnClick(id="hello")
   28.17 +    @On(event = CLICK, id="hello")
   28.18      static void hello() {
   28.19          Index.HELLO.setDisabled(true);
   28.20 +        Element.alert("Hello World!");
   28.21      }
   28.22  }
    29.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Jan 15 11:39:15 2013 +0100
    29.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Jan 21 15:57:01 2013 +0100
    29.3 @@ -19,6 +19,7 @@
    29.4  
    29.5  import java.io.IOException;
    29.6  import java.io.InputStream;
    29.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    29.8  import org.apidesign.javap.AnnotationParser;
    29.9  import org.apidesign.javap.ClassData;
   29.10  import org.apidesign.javap.FieldData;
   29.11 @@ -51,7 +52,7 @@
   29.12      /*
   29.13       * @param resourcePath name of resources to read
   29.14       */
   29.15 -    protected abstract void requireScript(String resourcePath);
   29.16 +    protected abstract void requireScript(String resourcePath) throws IOException;
   29.17      
   29.18      /** Allows subclasses to redefine what field a function representing a
   29.19       * class gets assigned. By default it returns the suggested name followed
   29.20 @@ -249,7 +250,7 @@
   29.21                  new LocalsMapper(stackMapIterator.getArguments());
   29.22  
   29.23          out.append(prefix).append(name).append(" = function(");
   29.24 -        lmapper.outputArguments(out);
   29.25 +        lmapper.outputArguments(out, m.isStatic());
   29.26          out.append(") {").append("\n");
   29.27  
   29.28          final byte[] byteCodes = m.getCode();
   29.29 @@ -263,32 +264,8 @@
   29.30  
   29.31          final StackMapper smapper = new StackMapper();
   29.32  
   29.33 -        final int maxLocals = m.getMaxLocals();
   29.34 -        if (maxLocals > 0) {
   29.35 -            // TODO: generate only used local variables
   29.36 -            for (int j = 0; j <= VarType.LAST; ++j) {
   29.37 -                out.append("\n  var ").append(Variable.getLocalVariable(j, 0));
   29.38 -                for (int i = 1; i < maxLocals; ++i) {
   29.39 -                    out.append(", ");
   29.40 -                    out.append(Variable.getLocalVariable(j, i));
   29.41 -                }
   29.42 -                out.append(';');
   29.43 -            }
   29.44 -        }
   29.45 -
   29.46 -        // maxStack includes two stack positions for every pushed long / double
   29.47 -        // so this might generate more stack variables than we need
   29.48 -        final int maxStack = m.getMaxStack();
   29.49 -        if (maxStack > 0) {
   29.50 -            // TODO: generate only used stack variables
   29.51 -            for (int j = 0; j <= VarType.LAST; ++j) {
   29.52 -                out.append("\n  var ").append(Variable.getStackVariable(j, 0));
   29.53 -                for (int i = 1; i < maxStack; ++i) {
   29.54 -                    out.append(", ");
   29.55 -                    out.append(Variable.getStackVariable(j, i));
   29.56 -                }
   29.57 -                out.append(';');
   29.58 -            }
   29.59 +        if (!m.isStatic()) {
   29.60 +            out.append("  var ").append(" lcA0 = this;\n");
   29.61          }
   29.62  
   29.63          int lastStackFrame = -1;
   29.64 @@ -321,174 +298,184 @@
   29.65              final int c = readByte(byteCodes, i);
   29.66              switch (c) {
   29.67                  case opc_aload_0:
   29.68 -                    emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(0));
   29.69 +                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(0));
   29.70                      break;
   29.71                  case opc_iload_0:
   29.72 -                    emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(0));
   29.73 +                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(0));
   29.74                      break;
   29.75                  case opc_lload_0:
   29.76 -                    emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(0));
   29.77 +                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(0));
   29.78                      break;
   29.79                  case opc_fload_0:
   29.80 -                    emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(0));
   29.81 +                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(0));
   29.82                      break;
   29.83                  case opc_dload_0:
   29.84 -                    emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(0));
   29.85 +                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(0));
   29.86                      break;
   29.87                  case opc_aload_1:
   29.88 -                    emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(1));
   29.89 +                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(1));
   29.90                      break;
   29.91                  case opc_iload_1:
   29.92 -                    emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(1));
   29.93 +                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(1));
   29.94                      break;
   29.95                  case opc_lload_1:
   29.96 -                    emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(1));
   29.97 +                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(1));
   29.98                      break;
   29.99                  case opc_fload_1:
  29.100 -                    emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(1));
  29.101 +                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(1));
  29.102                      break;
  29.103                  case opc_dload_1:
  29.104 -                    emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(1));
  29.105 +                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(1));
  29.106                      break;
  29.107                  case opc_aload_2:
  29.108 -                    emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(2));
  29.109 +                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(2));
  29.110                      break;
  29.111                  case opc_iload_2:
  29.112 -                    emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(2));
  29.113 +                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(2));
  29.114                      break;
  29.115                  case opc_lload_2:
  29.116 -                    emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(2));
  29.117 +                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(2));
  29.118                      break;
  29.119                  case opc_fload_2:
  29.120 -                    emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(2));
  29.121 +                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(2));
  29.122                      break;
  29.123                  case opc_dload_2:
  29.124 -                    emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(2));
  29.125 +                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(2));
  29.126                      break;
  29.127                  case opc_aload_3:
  29.128 -                    emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(3));
  29.129 +                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(3));
  29.130                      break;
  29.131                  case opc_iload_3:
  29.132 -                    emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(3));
  29.133 +                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(3));
  29.134                      break;
  29.135                  case opc_lload_3:
  29.136 -                    emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(3));
  29.137 +                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(3));
  29.138                      break;
  29.139                  case opc_fload_3:
  29.140 -                    emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(3));
  29.141 +                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(3));
  29.142                      break;
  29.143                  case opc_dload_3:
  29.144 -                    emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(3));
  29.145 +                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(3));
  29.146                      break;
  29.147                  case opc_iload: {
  29.148                      final int indx = readByte(byteCodes, ++i);
  29.149 -                    emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(indx));
  29.150 +                    emit(out, "var @1 = @2;",
  29.151 +                         smapper.pushI(), lmapper.getI(indx));
  29.152                      break;
  29.153                  }
  29.154                  case opc_lload: {
  29.155                      final int indx = readByte(byteCodes, ++i);
  29.156 -                    emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(indx));
  29.157 +                    emit(out, "var @1 = @2;",
  29.158 +                         smapper.pushL(), lmapper.getL(indx));
  29.159                      break;
  29.160                  }
  29.161                  case opc_fload: {
  29.162                      final int indx = readByte(byteCodes, ++i);
  29.163 -                    emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(indx));
  29.164 +                    emit(out, "var @1 = @2;",
  29.165 +                         smapper.pushF(), lmapper.getF(indx));
  29.166                      break;
  29.167                  }
  29.168                  case opc_dload: {
  29.169                      final int indx = readByte(byteCodes, ++i);
  29.170 -                    emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(indx));
  29.171 +                    emit(out, "var @1 = @2;",
  29.172 +                         smapper.pushD(), lmapper.getD(indx));
  29.173                      break;
  29.174                  }
  29.175                  case opc_aload: {
  29.176                      final int indx = readByte(byteCodes, ++i);
  29.177 -                    emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(indx));
  29.178 +                    emit(out, "var @1 = @2;",
  29.179 +                         smapper.pushA(), lmapper.getA(indx));
  29.180                      break;
  29.181                  }
  29.182                  case opc_istore: {
  29.183                      final int indx = readByte(byteCodes, ++i);
  29.184 -                    emit(out, "@1 = @2;", lmapper.setI(indx), smapper.popI());
  29.185 +                    emit(out, "var @1 = @2;",
  29.186 +                         lmapper.setI(indx), smapper.popI());
  29.187                      break;
  29.188                  }
  29.189                  case opc_lstore: {
  29.190                      final int indx = readByte(byteCodes, ++i);
  29.191 -                    emit(out, "@1 = @2;", lmapper.setL(indx), smapper.popL());
  29.192 +                    emit(out, "var @1 = @2;",
  29.193 +                         lmapper.setL(indx), smapper.popL());
  29.194                      break;
  29.195                  }
  29.196                  case opc_fstore: {
  29.197                      final int indx = readByte(byteCodes, ++i);
  29.198 -                    emit(out, "@1 = @2;", lmapper.setF(indx), smapper.popF());
  29.199 +                    emit(out, "var @1 = @2;",
  29.200 +                         lmapper.setF(indx), smapper.popF());
  29.201                      break;
  29.202                  }
  29.203                  case opc_dstore: {
  29.204                      final int indx = readByte(byteCodes, ++i);
  29.205 -                    emit(out, "@1 = @2;", lmapper.setD(indx), smapper.popD());
  29.206 +                    emit(out, "var @1 = @2;",
  29.207 +                         lmapper.setD(indx), smapper.popD());
  29.208                      break;
  29.209                  }
  29.210                  case opc_astore: {
  29.211                      final int indx = readByte(byteCodes, ++i);
  29.212 -                    emit(out, "@1 = @2;", lmapper.setA(indx), smapper.popA());
  29.213 +                    emit(out, "var @1 = @2;",
  29.214 +                         lmapper.setA(indx), smapper.popA());
  29.215                      break;
  29.216                  }
  29.217                  case opc_astore_0:
  29.218 -                    emit(out, "@1 = @2;", lmapper.setA(0), smapper.popA());
  29.219 +                    emit(out, "var @1 = @2;", lmapper.setA(0), smapper.popA());
  29.220                      break;
  29.221                  case opc_istore_0:
  29.222 -                    emit(out, "@1 = @2;", lmapper.setI(0), smapper.popI());
  29.223 +                    emit(out, "var @1 = @2;", lmapper.setI(0), smapper.popI());
  29.224                      break;
  29.225                  case opc_lstore_0:
  29.226 -                    emit(out, "@1 = @2;", lmapper.setL(0), smapper.popL());
  29.227 +                    emit(out, "var @1 = @2;", lmapper.setL(0), smapper.popL());
  29.228                      break;
  29.229                  case opc_fstore_0:
  29.230 -                    emit(out, "@1 = @2;", lmapper.setF(0), smapper.popF());
  29.231 +                    emit(out, "var @1 = @2;", lmapper.setF(0), smapper.popF());
  29.232                      break;
  29.233                  case opc_dstore_0:
  29.234 -                    emit(out, "@1 = @2;", lmapper.setD(0), smapper.popD());
  29.235 +                    emit(out, "var @1 = @2;", lmapper.setD(0), smapper.popD());
  29.236                      break;
  29.237                  case opc_astore_1:
  29.238 -                    emit(out, "@1 = @2;", lmapper.setA(1), smapper.popA());
  29.239 +                    emit(out, "var @1 = @2;", lmapper.setA(1), smapper.popA());
  29.240                      break;
  29.241                  case opc_istore_1:
  29.242 -                    emit(out, "@1 = @2;", lmapper.setI(1), smapper.popI());
  29.243 +                    emit(out, "var @1 = @2;", lmapper.setI(1), smapper.popI());
  29.244                      break;
  29.245                  case opc_lstore_1:
  29.246 -                    emit(out, "@1 = @2;", lmapper.setL(1), smapper.popL());
  29.247 +                    emit(out, "var @1 = @2;", lmapper.setL(1), smapper.popL());
  29.248                      break;
  29.249                  case opc_fstore_1:
  29.250 -                    emit(out, "@1 = @2;", lmapper.setF(1), smapper.popF());
  29.251 +                    emit(out, "var @1 = @2;", lmapper.setF(1), smapper.popF());
  29.252                      break;
  29.253                  case opc_dstore_1:
  29.254 -                    emit(out, "@1 = @2;", lmapper.setD(1), smapper.popD());
  29.255 +                    emit(out, "var @1 = @2;", lmapper.setD(1), smapper.popD());
  29.256                      break;
  29.257                  case opc_astore_2:
  29.258 -                    emit(out, "@1 = @2;", lmapper.setA(2), smapper.popA());
  29.259 +                    emit(out, "var @1 = @2;", lmapper.setA(2), smapper.popA());
  29.260                      break;
  29.261                  case opc_istore_2:
  29.262 -                    emit(out, "@1 = @2;", lmapper.setI(2), smapper.popI());
  29.263 +                    emit(out, "var @1 = @2;", lmapper.setI(2), smapper.popI());
  29.264                      break;
  29.265                  case opc_lstore_2:
  29.266 -                    emit(out, "@1 = @2;", lmapper.setL(2), smapper.popL());
  29.267 +                    emit(out, "var @1 = @2;", lmapper.setL(2), smapper.popL());
  29.268                      break;
  29.269                  case opc_fstore_2:
  29.270 -                    emit(out, "@1 = @2;", lmapper.setF(2), smapper.popF());
  29.271 +                    emit(out, "var @1 = @2;", lmapper.setF(2), smapper.popF());
  29.272                      break;
  29.273                  case opc_dstore_2:
  29.274 -                    emit(out, "@1 = @2;", lmapper.setD(2), smapper.popD());
  29.275 +                    emit(out, "var @1 = @2;", lmapper.setD(2), smapper.popD());
  29.276                      break;
  29.277                  case opc_astore_3:
  29.278 -                    emit(out, "@1 = @2;", lmapper.setA(3), smapper.popA());
  29.279 +                    emit(out, "var @1 = @2;", lmapper.setA(3), smapper.popA());
  29.280                      break;
  29.281                  case opc_istore_3:
  29.282 -                    emit(out, "@1 = @2;", lmapper.setI(3), smapper.popI());
  29.283 +                    emit(out, "var @1 = @2;", lmapper.setI(3), smapper.popI());
  29.284                      break;
  29.285                  case opc_lstore_3:
  29.286 -                    emit(out, "@1 = @2;", lmapper.setL(3), smapper.popL());
  29.287 +                    emit(out, "var @1 = @2;", lmapper.setL(3), smapper.popL());
  29.288                      break;
  29.289                  case opc_fstore_3:
  29.290 -                    emit(out, "@1 = @2;", lmapper.setF(3), smapper.popF());
  29.291 +                    emit(out, "var @1 = @2;", lmapper.setF(3), smapper.popF());
  29.292                      break;
  29.293                  case opc_dstore_3:
  29.294 -                    emit(out, "@1 = @2;", lmapper.setD(3), smapper.popD());
  29.295 +                    emit(out, "var @1 = @2;", lmapper.setD(3), smapper.popD());
  29.296                      break;
  29.297                  case opc_iadd:
  29.298                      emit(out, "@1 = @1.add32(@2);", smapper.getI(1), smapper.popI());
  29.299 @@ -631,105 +618,105 @@
  29.300                      emit(out, "return @1;", smapper.popA());
  29.301                      break;
  29.302                  case opc_i2l:
  29.303 -                    emit(out, "@2 = @1;", smapper.popI(), smapper.pushL());
  29.304 +                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushL());
  29.305                      break;
  29.306                  case opc_i2f:
  29.307 -                    emit(out, "@2 = @1;", smapper.popI(), smapper.pushF());
  29.308 +                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushF());
  29.309                      break;
  29.310                  case opc_i2d:
  29.311 -                    emit(out, "@2 = @1;", smapper.popI(), smapper.pushD());
  29.312 +                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushD());
  29.313                      break;
  29.314                  case opc_l2i:
  29.315 -                    emit(out, "@2 = @1;", smapper.popL(), smapper.pushI());
  29.316 +                    emit(out, "var @2 = @1;", smapper.popL(), smapper.pushI());
  29.317                      break;
  29.318                      // max int check?
  29.319                  case opc_l2f:
  29.320 -                    emit(out, "@2 = @1;", smapper.popL(), smapper.pushF());
  29.321 +                    emit(out, "var @2 = @1;", smapper.popL(), smapper.pushF());
  29.322                      break;
  29.323                  case opc_l2d:
  29.324 -                    emit(out, "@2 = @1;", smapper.popL(), smapper.pushD());
  29.325 +                    emit(out, "var @2 = @1;", smapper.popL(), smapper.pushD());
  29.326                      break;
  29.327                  case opc_f2d:
  29.328 -                    emit(out, "@2 = @1;", smapper.popF(), smapper.pushD());
  29.329 +                    emit(out, "var @2 = @1;", smapper.popF(), smapper.pushD());
  29.330                      break;
  29.331                  case opc_d2f:
  29.332 -                    emit(out, "@2 = @1;", smapper.popD(), smapper.pushF());
  29.333 +                    emit(out, "var @2 = @1;", smapper.popD(), smapper.pushF());
  29.334                      break;
  29.335                  case opc_f2i:
  29.336 -                    emit(out, "@2 = Math.floor(@1);",
  29.337 +                    emit(out, "var @2 = Math.floor(@1);",
  29.338                           smapper.popF(), smapper.pushI());
  29.339                      break;
  29.340                  case opc_f2l:
  29.341 -                    emit(out, "@2 = Math.floor(@1);",
  29.342 +                    emit(out, "var @2 = Math.floor(@1);",
  29.343                           smapper.popF(), smapper.pushL());
  29.344                      break;
  29.345                  case opc_d2i:
  29.346 -                    emit(out, "@2 = Math.floor(@1);",
  29.347 +                    emit(out, "var @2 = Math.floor(@1);",
  29.348                           smapper.popD(), smapper.pushI());
  29.349                      break;
  29.350                  case opc_d2l:
  29.351 -                    emit(out, "@2 = Math.floor(@1);",
  29.352 +                    emit(out, "var @2 = Math.floor(@1);",
  29.353                           smapper.popD(), smapper.pushL());
  29.354                      break;
  29.355                  case opc_i2b:
  29.356 -                    emit(out, "@1 = @1.toInt8();", smapper.getI(0));
  29.357 +                    emit(out, "var @1 = @1.toInt8();", smapper.getI(0));
  29.358                      break;
  29.359                  case opc_i2c:
  29.360                      out.append("{ /* number conversion */ }");
  29.361                      break;
  29.362                  case opc_i2s:
  29.363 -                    emit(out, "@1 = @1.toInt16();", smapper.getI(0));
  29.364 +                    emit(out, "var @1 = @1.toInt16();", smapper.getI(0));
  29.365                      break;
  29.366                  case opc_aconst_null:
  29.367 -                    emit(out, "@1 = null;", smapper.pushA());
  29.368 +                    emit(out, "var @1 = null;", smapper.pushA());
  29.369                      break;
  29.370                  case opc_iconst_m1:
  29.371 -                    emit(out, "@1 = -1;", smapper.pushI());
  29.372 +                    emit(out, "var @1 = -1;", smapper.pushI());
  29.373                      break;
  29.374                  case opc_iconst_0:
  29.375 -                    emit(out, "@1 = 0;", smapper.pushI());
  29.376 +                    emit(out, "var @1 = 0;", smapper.pushI());
  29.377                      break;
  29.378                  case opc_dconst_0:
  29.379 -                    emit(out, "@1 = 0;", smapper.pushD());
  29.380 +                    emit(out, "var @1 = 0;", smapper.pushD());
  29.381                      break;
  29.382                  case opc_lconst_0:
  29.383 -                    emit(out, "@1 = 0;", smapper.pushL());
  29.384 +                    emit(out, "var @1 = 0;", smapper.pushL());
  29.385                      break;
  29.386                  case opc_fconst_0:
  29.387 -                    emit(out, "@1 = 0;", smapper.pushF());
  29.388 +                    emit(out, "var @1 = 0;", smapper.pushF());
  29.389                      break;
  29.390                  case opc_iconst_1:
  29.391 -                    emit(out, "@1 = 1;", smapper.pushI());
  29.392 +                    emit(out, "var @1 = 1;", smapper.pushI());
  29.393                      break;
  29.394                  case opc_lconst_1:
  29.395 -                    emit(out, "@1 = 1;", smapper.pushL());
  29.396 +                    emit(out, "var @1 = 1;", smapper.pushL());
  29.397                      break;
  29.398                  case opc_fconst_1:
  29.399 -                    emit(out, "@1 = 1;", smapper.pushF());
  29.400 +                    emit(out, "var @1 = 1;", smapper.pushF());
  29.401                      break;
  29.402                  case opc_dconst_1:
  29.403 -                    emit(out, "@1 = 1;", smapper.pushD());
  29.404 +                    emit(out, "var @1 = 1;", smapper.pushD());
  29.405                      break;
  29.406                  case opc_iconst_2:
  29.407 -                    emit(out, "@1 = 2;", smapper.pushI());
  29.408 +                    emit(out, "var @1 = 2;", smapper.pushI());
  29.409                      break;
  29.410                  case opc_fconst_2:
  29.411 -                    emit(out, "@1 = 2;", smapper.pushF());
  29.412 +                    emit(out, "var @1 = 2;", smapper.pushF());
  29.413                      break;
  29.414                  case opc_iconst_3:
  29.415 -                    emit(out, "@1 = 3;", smapper.pushI());
  29.416 +                    emit(out, "var @1 = 3;", smapper.pushI());
  29.417                      break;
  29.418                  case opc_iconst_4:
  29.419 -                    emit(out, "@1 = 4;", smapper.pushI());
  29.420 +                    emit(out, "var @1 = 4;", smapper.pushI());
  29.421                      break;
  29.422                  case opc_iconst_5:
  29.423 -                    emit(out, "@1 = 5;", smapper.pushI());
  29.424 +                    emit(out, "var @1 = 5;", smapper.pushI());
  29.425                      break;
  29.426                  case opc_ldc: {
  29.427                      int indx = readByte(byteCodes, ++i);
  29.428                      String v = encodeConstant(indx);
  29.429                      int type = VarType.fromConstantType(jc.getTag(indx));
  29.430 -                    emit(out, "@1 = @2;", smapper.pushT(type), v);
  29.431 +                    emit(out, "var @1 = @2;", smapper.pushT(type), v);
  29.432                      break;
  29.433                  }
  29.434                  case opc_ldc_w:
  29.435 @@ -738,21 +725,21 @@
  29.436                      i += 2;
  29.437                      String v = encodeConstant(indx);
  29.438                      int type = VarType.fromConstantType(jc.getTag(indx));
  29.439 -                    emit(out, "@1 = @2;", smapper.pushT(type), v);
  29.440 +                    emit(out, "var @1 = @2;", smapper.pushT(type), v);
  29.441                      break;
  29.442                  }
  29.443                  case opc_lcmp:
  29.444 -                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.445 +                    emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.446                           smapper.popL(), smapper.popL(), smapper.pushI());
  29.447                      break;
  29.448                  case opc_fcmpl:
  29.449                  case opc_fcmpg:
  29.450 -                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.451 +                    emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.452                           smapper.popF(), smapper.popF(), smapper.pushI());
  29.453                      break;
  29.454                  case opc_dcmpl:
  29.455                  case opc_dcmpg:
  29.456 -                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.457 +                    emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
  29.458                           smapper.popD(), smapper.popD(), smapper.pushI());
  29.459                      break;
  29.460                  case opc_if_acmpeq:
  29.461 @@ -902,91 +889,108 @@
  29.462                  case opc_new: {
  29.463                      int indx = readIntArg(byteCodes, i);
  29.464                      String ci = jc.getClassName(indx);
  29.465 -                    emit(out, "@1 = new @2;",
  29.466 +                    emit(out, "var @1 = new @2;",
  29.467                           smapper.pushA(), accessClass(ci.replace('/', '_')));
  29.468                      addReference(ci);
  29.469                      i += 2;
  29.470                      break;
  29.471                  }
  29.472                  case opc_newarray:
  29.473 -                    ++i; // skip type of array
  29.474 -                    emit(out, "@2 = new Array(@1).fillWith(0);",
  29.475 -                         smapper.popI(), smapper.pushA());
  29.476 +                    int atype = readByte(byteCodes, ++i);
  29.477 +                    String jvmType;
  29.478 +                    switch (atype) {
  29.479 +                        case 4: jvmType = "[Z"; break;
  29.480 +                        case 5: jvmType = "[C"; break;
  29.481 +                        case 6: jvmType = "[F"; break;
  29.482 +                        case 7: jvmType = "[D"; break;
  29.483 +                        case 8: jvmType = "[B"; break;
  29.484 +                        case 9: jvmType = "[S"; break;
  29.485 +                        case 10: jvmType = "[I"; break;
  29.486 +                        case 11: jvmType = "[J"; break;
  29.487 +                        default: throw new IllegalStateException("Array type: " + atype);
  29.488 +                    }
  29.489 +                    emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
  29.490 +                         smapper.popI(), smapper.pushA(), jvmType);
  29.491                      break;
  29.492 -                case opc_anewarray:
  29.493 -                    i += 2; // skip type of array
  29.494 -                    emit(out, "@2 = new Array(@1).fillWith(null);",
  29.495 -                         smapper.popI(), smapper.pushA());
  29.496 +                case opc_anewarray: {
  29.497 +                    int type = readIntArg(byteCodes, i);
  29.498 +                    i += 2;
  29.499 +                    String typeName = jc.getClassName(type);
  29.500 +                    if (typeName.startsWith("[")) {
  29.501 +                        typeName = "[" + typeName;
  29.502 +                    } else {
  29.503 +                        typeName = "[L" + typeName + ";";
  29.504 +                    }
  29.505 +                    emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
  29.506 +                         smapper.popI(), smapper.pushA(), typeName);
  29.507                      break;
  29.508 +                }
  29.509                  case opc_multianewarray: {
  29.510 +                    int type = readIntArg(byteCodes, i);
  29.511                      i += 2;
  29.512 +                    String typeName = jc.getClassName(type);
  29.513                      int dim = readByte(byteCodes, ++i);
  29.514 -                    out.append("{ var a0 = new Array(").append(smapper.popI())
  29.515 -                       .append(").fillWith(null);");
  29.516 -                    for (int d = 1; d < dim; d++) {
  29.517 -                        out.append("\n  var l" + d).append(" = ")
  29.518 -                           .append(smapper.popI()).append(';');
  29.519 -                        out.append("\n  for (var i" + d).append (" = 0; i" + d).
  29.520 -                            append(" < a" + (d - 1)).
  29.521 -                            append(".length; i" + d).append("++) {");
  29.522 -                        out.append("\n    var a" + d).
  29.523 -                            append (" = new Array(l" + d).append(").fillWith(null);");
  29.524 -                        out.append("\n    a" + (d - 1)).append("[i" + d).append("] = a" + d).
  29.525 -                            append(";");
  29.526 +                    StringBuilder dims = new StringBuilder();
  29.527 +                    dims.append('[');
  29.528 +                    for (int d = 0; d < dim; d++) {
  29.529 +                        if (d != 0) {
  29.530 +                            dims.append(",");
  29.531 +                        }
  29.532 +                        dims.append(smapper.popI());
  29.533                      }
  29.534 -                    for (int d = 1; d < dim; d++) {
  29.535 -                        out.append("\n  }");
  29.536 -                    }
  29.537 -                    out.append("\n").append(smapper.pushA()).append(" = a0; }");
  29.538 +                    dims.append(']');
  29.539 +                    emit(out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
  29.540 +                         dims.toString(), smapper.pushA(), typeName);
  29.541                      break;
  29.542                  }
  29.543                  case opc_arraylength:
  29.544 -                    emit(out, "@2 = @1.length;", smapper.popA(), smapper.pushI());
  29.545 +                    emit(out, "var @2 = @1.length;",
  29.546 +                         smapper.popA(), smapper.pushI());
  29.547                      break;
  29.548                  case opc_lastore:
  29.549 -                    emit(out, "@3[@2] = @1;",
  29.550 +                    emit(out, "@3.at(@2, @1);",
  29.551                           smapper.popL(), smapper.popI(), smapper.popA());
  29.552                      break;
  29.553                  case opc_fastore:
  29.554 -                    emit(out, "@3[@2] = @1;",
  29.555 +                    emit(out, "@3.at(@2, @1);",
  29.556                           smapper.popF(), smapper.popI(), smapper.popA());
  29.557                      break;
  29.558                  case opc_dastore:
  29.559 -                    emit(out, "@3[@2] = @1;",
  29.560 +                    emit(out, "@3.at(@2, @1);",
  29.561                           smapper.popD(), smapper.popI(), smapper.popA());
  29.562                      break;
  29.563                  case opc_aastore:
  29.564 -                    emit(out, "@3[@2] = @1;",
  29.565 +                    emit(out, "@3.at(@2, @1);",
  29.566                           smapper.popA(), smapper.popI(), smapper.popA());
  29.567                      break;
  29.568                  case opc_iastore:
  29.569                  case opc_bastore:
  29.570                  case opc_castore:
  29.571                  case opc_sastore:
  29.572 -                    emit(out, "@3[@2] = @1;",
  29.573 +                    emit(out, "@3.at(@2, @1);",
  29.574                           smapper.popI(), smapper.popI(), smapper.popA());
  29.575                      break;
  29.576                  case opc_laload:
  29.577 -                    emit(out, "@3 = @2[@1];",
  29.578 +                    emit(out, "var @3 = @2.at(@1);",
  29.579                           smapper.popI(), smapper.popA(), smapper.pushL());
  29.580                      break;
  29.581                  case opc_faload:
  29.582 -                    emit(out, "@3 = @2[@1];",
  29.583 +                    emit(out, "var @3 = @2.at(@1);",
  29.584                           smapper.popI(), smapper.popA(), smapper.pushF());
  29.585                      break;
  29.586                  case opc_daload:
  29.587 -                    emit(out, "@3 = @2[@1];",
  29.588 +                    emit(out, "var @3 = @2.at(@1);",
  29.589                           smapper.popI(), smapper.popA(), smapper.pushD());
  29.590                      break;
  29.591                  case opc_aaload:
  29.592 -                    emit(out, "@3 = @2[@1];",
  29.593 +                    emit(out, "var @3 = @2.at(@1);",
  29.594                           smapper.popI(), smapper.popA(), smapper.pushA());
  29.595                      break;
  29.596                  case opc_iaload:
  29.597                  case opc_baload:
  29.598                  case opc_caload:
  29.599                  case opc_saload:
  29.600 -                    emit(out, "@3 = @2[@1];",
  29.601 +                    emit(out, "var @3 = @2.at(@1);",
  29.602                           smapper.popI(), smapper.popA(), smapper.pushI());
  29.603                      break;
  29.604                  case opc_pop:
  29.605 @@ -996,17 +1000,18 @@
  29.606                      break;
  29.607                  case opc_dup: {
  29.608                      final Variable v = smapper.get(0);
  29.609 -                    emit(out, "@1 = @2;", smapper.pushT(v.getType()), v);
  29.610 +                    emit(out, "var @1 = @2;", smapper.pushT(v.getType()), v);
  29.611                      break;
  29.612                  }
  29.613                  case opc_dup2: {
  29.614                      if (smapper.get(0).isCategory2()) {
  29.615                          final Variable v = smapper.get(0);
  29.616 -                        emit(out, "@1 = @2;", smapper.pushT(v.getType()), v);
  29.617 +                        emit(out, "var @1 = @2;",
  29.618 +                             smapper.pushT(v.getType()), v);
  29.619                      } else {
  29.620                          final Variable v1 = smapper.get(0);
  29.621                          final Variable v2 = smapper.get(1);
  29.622 -                        emit(out, "{ @1 = @2; @3 = @4; }",
  29.623 +                        emit(out, "var @1 = @2, @3 = @4;",
  29.624                               smapper.pushT(v2.getType()), v2,
  29.625                               smapper.pushT(v1.getType()), v1);
  29.626                      }
  29.627 @@ -1019,7 +1024,7 @@
  29.628                      final Variable vo2 = smapper.pushT(vi2.getType());
  29.629                      final Variable vo1 = smapper.pushT(vi1.getType());
  29.630  
  29.631 -                    emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
  29.632 +                    emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
  29.633                           vo1, vi1, vo2, vi2, vo3, vo1);
  29.634                      break;
  29.635                  }
  29.636 @@ -1031,7 +1036,7 @@
  29.637                          final Variable vo2 = smapper.pushT(vi2.getType());
  29.638                          final Variable vo1 = smapper.pushT(vi1.getType());
  29.639  
  29.640 -                        emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
  29.641 +                        emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
  29.642                               vo1, vi1, vo2, vi2, vo3, vo1);
  29.643                      } else {
  29.644                          final Variable vi1 = smapper.pop();
  29.645 @@ -1042,17 +1047,17 @@
  29.646                          final Variable vo2 = smapper.pushT(vi2.getType());
  29.647                          final Variable vo1 = smapper.pushT(vi1.getType());
  29.648  
  29.649 -                        emit(out, "{ @1 = @2; @3 = @4; @5 = @6; @7 = @8; }",
  29.650 +                        emit(out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
  29.651                               vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
  29.652                      }
  29.653                      break;
  29.654                  }
  29.655                  case opc_bipush:
  29.656 -                    emit(out, "@1 = @2;",
  29.657 +                    emit(out, "var @1 = @2;",
  29.658                           smapper.pushI(), Integer.toString(byteCodes[++i]));
  29.659                      break;
  29.660                  case opc_sipush:
  29.661 -                    emit(out, "@1 = @2;",
  29.662 +                    emit(out, "var @1 = @2;",
  29.663                           smapper.pushI(),
  29.664                           Integer.toString(readIntArg(byteCodes, i)));
  29.665                      i += 2;
  29.666 @@ -1061,7 +1066,7 @@
  29.667                      int indx = readIntArg(byteCodes, i);
  29.668                      String[] fi = jc.getFieldInfoName(indx);
  29.669                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  29.670 -                    emit(out, "@2 = @1.fld_@3;",
  29.671 +                    emit(out, "var @2 = @1.fld_@3;",
  29.672                           smapper.popA(), smapper.pushT(type), fi[1]);
  29.673                      i += 2;
  29.674                      break;
  29.675 @@ -1070,7 +1075,7 @@
  29.676                      int indx = readIntArg(byteCodes, i);
  29.677                      String[] fi = jc.getFieldInfoName(indx);
  29.678                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  29.679 -                    emit(out, "@1 = @2(false).constructor.@3;",
  29.680 +                    emit(out, "var @1 = @2(false).constructor.@3;",
  29.681                           smapper.pushT(type),
  29.682                           accessClass(fi[0].replace('/', '_')), fi[1]);
  29.683                      i += 2;
  29.684 @@ -1113,7 +1118,7 @@
  29.685                  case opc_instanceof: {
  29.686                      int indx = readIntArg(byteCodes, i);
  29.687                      final String type = jc.getClassName(indx);
  29.688 -                    emit(out, "@2 = @1.$instOf_@3 ? 1 : 0;",
  29.689 +                    emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;",
  29.690                           smapper.popA(), smapper.pushI(),
  29.691                           type.replace('/', '_'));
  29.692                      i += 2;
  29.693 @@ -1123,7 +1128,7 @@
  29.694                      final Variable v = smapper.popA();
  29.695                      smapper.clear();
  29.696  
  29.697 -                    emit(out, "{ @1 = @2; throw @2; }",
  29.698 +                    emit(out, "{ var @1 = @2; throw @2; }",
  29.699                           smapper.pushA(), v);
  29.700                      break;
  29.701                  }
  29.702 @@ -1323,7 +1328,8 @@
  29.703          }
  29.704  
  29.705          if (returnType[0] != 'V') {
  29.706 -            out.append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  29.707 +            out.append("var ")
  29.708 +               .append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  29.709                 .append(" = ");
  29.710          }
  29.711  
  29.712 @@ -1334,7 +1340,11 @@
  29.713              out.append("constructor.");
  29.714          }
  29.715          out.append(mn);
  29.716 -        out.append('(');
  29.717 +        if (isStatic) {
  29.718 +            out.append('(');
  29.719 +        } else {
  29.720 +            out.append(".call(");
  29.721 +        }
  29.722          if (numArguments > 0) {
  29.723              out.append(vars[0]);
  29.724              for (int j = 1; j < numArguments; ++j) {
  29.725 @@ -1363,17 +1373,19 @@
  29.726          }
  29.727  
  29.728          if (returnType[0] != 'V') {
  29.729 -            out.append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  29.730 +            out.append("var ")
  29.731 +               .append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  29.732                 .append(" = ");
  29.733          }
  29.734  
  29.735          out.append(vars[0]).append('.');
  29.736          out.append(mn);
  29.737          out.append('(');
  29.738 -        out.append(vars[0]);
  29.739 +        String sep = "";
  29.740          for (int j = 1; j < numArguments; ++j) {
  29.741 -            out.append(", ");
  29.742 +            out.append(sep);
  29.743              out.append(vars[j]);
  29.744 +            sep = ", ";
  29.745          }
  29.746          out.append(");");
  29.747          i += 2;
  29.748 @@ -1447,15 +1459,8 @@
  29.749          final String mn = findMethodName(m, cnt);
  29.750          out.append(prefix).append(mn);
  29.751          out.append(" = function(");
  29.752 -        String space;
  29.753 -        int index;
  29.754 -        if (!isStatic) {                
  29.755 -            space = outputArg(out, p.args, 0);
  29.756 -            index = 1;
  29.757 -        } else {
  29.758 -            space = "";
  29.759 -            index = 0;
  29.760 -        }
  29.761 +        String space = "";
  29.762 +        int index = 0;
  29.763          for (int i = 0; i < cnt.length(); i++) {
  29.764              out.append(space);
  29.765              space = outputArg(out, p.args, index);
  29.766 @@ -1601,15 +1606,15 @@
  29.767                  addReference(classInternalName);
  29.768                  if ("java/lang/Throwable".equals(classInternalName)) {
  29.769                      out.append("if (e.$instOf_java_lang_Throwable) {");
  29.770 -                    out.append("  stA0 = e;");
  29.771 +                    out.append("  var stA0 = e;");
  29.772                      out.append("} else {");
  29.773 -                    out.append("  stA0 = vm.java_lang_Throwable(true);");
  29.774 -                    out.append("  vm.java_lang_Throwable.cons__VLjava_lang_String_2(stA0, e.toString());");
  29.775 +                    out.append("  var stA0 = vm.java_lang_Throwable(true);");
  29.776 +                    out.append("  vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());");
  29.777                      out.append("}");
  29.778                      out.append("gt=" + e.handler_pc + "; continue;");
  29.779                  } else {
  29.780                      out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  29.781 -                    out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
  29.782 +                    out.append("gt=" + e.handler_pc + "; var stA0 = e; continue;");
  29.783                      out.append("}\n");
  29.784                  }
  29.785              } else {
  29.786 @@ -1619,7 +1624,7 @@
  29.787          if (finallyPC == -1) {
  29.788              out.append("throw e;");
  29.789          } else {
  29.790 -            out.append("gt=" + finallyPC + "; stA0 = e; continue;");
  29.791 +            out.append("gt=" + finallyPC + "; var stA0 = e; continue;");
  29.792          }
  29.793          out.append("\n}");
  29.794      }
    30.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java	Tue Jan 15 11:39:15 2013 +0100
    30.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java	Mon Jan 21 15:57:01 2013 +0100
    30.3 @@ -33,13 +33,14 @@
    30.4          localTypeRecords = new TypeArray(initTypeRecords);
    30.5      }
    30.6  
    30.7 -    public void outputArguments(final Appendable out) throws IOException {
    30.8 +    public void outputArguments(final Appendable out, boolean isStatic) throws IOException {
    30.9          final int argRecordCount = argTypeRecords.getSize();
   30.10 -        if (argRecordCount > 0) {
   30.11 -            Variable variable = getVariable(argTypeRecords, 0);
   30.12 +        int first = isStatic ? 0 : 1;
   30.13 +        if (argRecordCount > first) {
   30.14 +            Variable variable = getVariable(argTypeRecords, first);
   30.15              out.append(variable);
   30.16  
   30.17 -            int i = variable.isCategory2() ? 2 : 1;
   30.18 +            int i = first + (variable.isCategory2() ? 2 : 1);
   30.19              while (i < argRecordCount) {
   30.20                  variable = getVariable(argTypeRecords, i);
   30.21                  out.append(", ");
    31.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue Jan 15 11:39:15 2013 +0100
    31.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Mon Jan 21 15:57:01 2013 +0100
    31.3 @@ -117,7 +117,7 @@
    31.4              + "    var loader = {};\n"
    31.5              + "    loader.vm = vm;\n"
    31.6              + "    loader.loadClass = function(name) {\n"
    31.7 -            + "      var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
    31.8 +            + "      var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
    31.9              + "      var fn = vm[attr];\n"
   31.10              + "      if (fn) return fn(false);\n"
   31.11              + "      if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
    32.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Tue Jan 15 11:39:15 2013 +0100
    32.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Mon Jan 21 15:57:01 2013 +0100
    32.3 @@ -19,6 +19,7 @@
    32.4  
    32.5  import java.io.ByteArrayInputStream;
    32.6  import java.io.IOException;
    32.7 +import java.io.InputStream;
    32.8  import org.apidesign.bck2brwsr.core.JavaScriptBody;
    32.9  
   32.10  /**
   32.11 @@ -112,17 +113,17 @@
   32.12              this.lazy = vm;
   32.13          }
   32.14          
   32.15 -        @JavaScriptBody(args = {"self", "n"},
   32.16 +        @JavaScriptBody(args = {"n"},
   32.17          body =
   32.18 -        "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();"
   32.19 -        + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();"
   32.20 -        + "\nvar lazy = self.fld_lazy;"
   32.21 +        "var cls = n.replace__Ljava_lang_String_2CC('/','_').toString();"
   32.22 +        + "\nvar dot = n.replace__Ljava_lang_String_2CC('/','.').toString();"
   32.23 +        + "\nvar lazy = this.fld_lazy;"
   32.24          + "\nvar loader = lazy.fld_loader;"
   32.25          + "\nvar vm = loader.vm;"
   32.26          + "\nif (vm[cls]) return false;"
   32.27          + "\nvm[cls] = function() {"
   32.28          + "\n  var instance = arguments.length == 0 || arguments[0] === true;"
   32.29 -        + "\n  return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(lazy, dot, instance);"
   32.30 +        + "\n  return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(dot, instance);"
   32.31          + "\n};"
   32.32          + "\nreturn true;")
   32.33          @Override
   32.34 @@ -131,7 +132,17 @@
   32.35          }
   32.36  
   32.37          @Override
   32.38 -        protected void requireScript(String resourcePath) {
   32.39 +        protected void requireScript(String resourcePath) throws IOException {
   32.40 +            InputStream is = getClass().getResourceAsStream(resourcePath);
   32.41 +            StringBuilder sb = new StringBuilder();
   32.42 +            for (;;) {
   32.43 +                int ch = is.read();
   32.44 +                if (ch == -1) {
   32.45 +                    break;
   32.46 +                }
   32.47 +                sb.append((char)ch);
   32.48 +            }
   32.49 +            applyCode(lazy.loader, null, sb.toString(), false);
   32.50          }
   32.51  
   32.52          @Override
    33.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Tue Jan 15 11:39:15 2013 +0100
    33.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Mon Jan 21 15:57:01 2013 +0100
    33.3 @@ -51,6 +51,16 @@
    33.4          return doubles[4][0];
    33.5      }
    33.6      
    33.7 +    static double[][] dbls = new double[1][2];
    33.8 +    public static double twoDoubles() {
    33.9 +        return dbls[0][0] + dbls[0][0];
   33.10 +    }
   33.11 +
   33.12 +    static int[][] tints = new int[1][2];
   33.13 +    public static int twoInts() {
   33.14 +        return tints[0][0] + tints[0][0];
   33.15 +    }
   33.16 +    
   33.17      private static final Array[] ARR = { new Array(), new Array(), new Array() };
   33.18      
   33.19      private static Array[][] arr() {
    34.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Tue Jan 15 11:39:15 2013 +0100
    34.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Mon Jan 21 15:57:01 2013 +0100
    34.3 @@ -53,6 +53,17 @@
    34.4              Double.valueOf(105)
    34.5          );
    34.6      }
    34.7 +
    34.8 +    @Test public void twoDoubles() throws Exception {
    34.9 +        assertExec("Elements are initialized", Array.class, "twoDoubles__D", 
   34.10 +            Double.valueOf(0)
   34.11 +        );
   34.12 +    }
   34.13 +    @Test public void twoInts() throws Exception {
   34.14 +        assertExec("Elements are initialized", Array.class, "twoInts__I", 
   34.15 +            Double.valueOf(0)
   34.16 +        );
   34.17 +    }
   34.18      
   34.19      @Test public void doesCopyArrayWork() throws Exception {
   34.20          assertExec("Returns 'a'", Array.class, "copyArray__C", Double.valueOf('a'));
    35.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Tue Jan 15 11:39:15 2013 +0100
    35.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Mon Jan 21 15:57:01 2013 +0100
    35.3 @@ -125,4 +125,11 @@
    35.4      public static boolean iofObject() {
    35.5          return jsObj() instanceof Object;
    35.6      }
    35.7 +    
    35.8 +    public static int jscall() {
    35.9 +        return jsgetbytes(new Instance());
   35.10 +    }
   35.11 +    
   35.12 +    @JavaScriptBody(args = { "instance" }, body = "return instance.getByte__B();")
   35.13 +    private static native int jsgetbytes(Instance instance);
   35.14  }
    36.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Tue Jan 15 11:39:15 2013 +0100
    36.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Mon Jan 21 15:57:01 2013 +0100
    36.3 @@ -131,6 +131,14 @@
    36.4              Double.valueOf(1)
    36.5          );
    36.6      }
    36.7 +
    36.8 +    @Test public void jsCallingConvention() throws Exception {
    36.9 +        assertExec(
   36.10 +            "Pointer to 'this' is passed automatically (and not as a first argument)",
   36.11 +            Instance.class, "jscall__I",
   36.12 +            Double.valueOf(31)
   36.13 +        );
   36.14 +    }
   36.15      
   36.16      protected String startCompilationWith() {
   36.17          return "org/apidesign/vm4brwsr/Instance";
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Script.java	Mon Jan 21 15:57:01 2013 +0100
    37.3 @@ -0,0 +1,31 @@
    37.4 +/**
    37.5 + * Back 2 Browser Bytecode Translator
    37.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    37.7 + *
    37.8 + * This program is free software: you can redistribute it and/or modify
    37.9 + * it under the terms of the GNU General Public License as published by
   37.10 + * the Free Software Foundation, version 2 of the License.
   37.11 + *
   37.12 + * This program is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.15 + * GNU General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU General Public License
   37.18 + * along with this program. Look for COPYING file in the top folder.
   37.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   37.20 + */
   37.21 +package org.apidesign.vm4brwsr;
   37.22 +
   37.23 +import org.apidesign.bck2brwsr.core.ExtraJavaScript;
   37.24 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   37.25 +
   37.26 +/** Test to verify external scripts are processed in lazy mode.
   37.27 + *
   37.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   37.29 + */
   37.30 +@ExtraJavaScript(resource = "/org/apidesign/vm4brwsr/ko.js")
   37.31 +public class Script {
   37.32 +    @JavaScriptBody(args = {  }, body = "return ko !== null;")
   37.33 +    public static native boolean checkNotNull();
   37.34 +}
    38.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java	Tue Jan 15 11:39:15 2013 +0100
    38.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java	Mon Jan 21 15:57:01 2013 +0100
    38.3 @@ -67,6 +67,12 @@
    38.4          );
    38.5      }
    38.6  
    38.7 +    @Test public void loadClassWithAssociatedScript() throws Exception {
    38.8 +        assertExec("ko is defined", "test", true,
    38.9 +            Script.class.getName(), "checkNotNull__Z"
   38.10 +        );
   38.11 +    }
   38.12 +
   38.13      private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
   38.14          Object ret = null;
   38.15          try {
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/vm/src/test/resources/org/apidesign/vm4brwsr/ko.js	Mon Jan 21 15:57:01 2013 +0100
    39.3 @@ -0,0 +1,20 @@
    39.4 +/*
    39.5 + * Back 2 Browser Bytecode Translator
    39.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    39.7 + *
    39.8 + * This program is free software: you can redistribute it and/or modify
    39.9 + * it under the terms of the GNU General Public License as published by
   39.10 + * the Free Software Foundation, version 2 of the License.
   39.11 + *
   39.12 + * This program is distributed in the hope that it will be useful,
   39.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   39.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   39.15 + * GNU General Public License for more details.
   39.16 + *
   39.17 + * You should have received a copy of the GNU General Public License
   39.18 + * along with this program. Look for COPYING file in the top folder.
   39.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   39.20 + */
   39.21 +this.ko = {};
   39.22 +
   39.23 +
    40.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Tue Jan 15 11:39:15 2013 +0100
    40.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Mon Jan 21 15:57:01 2013 +0100
    40.3 @@ -49,6 +49,36 @@
    40.4          return sum;
    40.5      }
    40.6      
    40.7 +    @Compare public String noOutOfBounds() {
    40.8 +        return atIndex(1);
    40.9 +    }
   40.10 +
   40.11 +    @Compare public String outOfBounds() {
   40.12 +        return atIndex(5);
   40.13 +    }
   40.14 +
   40.15 +    @Compare public String outOfBoundsMinus() {
   40.16 +        return atIndex(-1);
   40.17 +    }
   40.18 +
   40.19 +    @Compare public String toOfBounds() {
   40.20 +        return toIndex(5);
   40.21 +    }
   40.22 +
   40.23 +    @Compare public String toOfBoundsMinus() {
   40.24 +        return toIndex(-1);
   40.25 +    }
   40.26 +
   40.27 +    private static final int[] arr = { 0, 1, 2 };
   40.28 +    public static String atIndex(int at) {
   40.29 +        return "at@" + arr[at];
   40.30 +    }
   40.31 +    public static String toIndex(int at) {
   40.32 +        arr[at] = 10;
   40.33 +        return "ok";
   40.34 +    }
   40.35 +    
   40.36 +    
   40.37      @Factory
   40.38      public static Object[] create() {
   40.39          return VMTest.create(CompareByteArrayTest.class);
    41.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Tue Jan 15 11:39:15 2013 +0100
    41.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Mon Jan 21 15:57:01 2013 +0100
    41.3 @@ -35,6 +35,10 @@
    41.4          return o.hashCode() - o.hashCode();
    41.5      }
    41.6      
    41.7 +    @Compare public int initializeInStatic() {
    41.8 +        return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
    41.9 +    }
   41.10 +    
   41.11      @Compare public int hashOfInt() {
   41.12          return Integer.valueOf(Integer.MAX_VALUE).hashCode();
   41.13      }
    42.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Tue Jan 15 11:39:15 2013 +0100
    42.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Mon Jan 21 15:57:01 2013 +0100
    42.3 @@ -28,6 +28,24 @@
    42.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
    42.5   */
    42.6  public class CompareStringsTest {
    42.7 +    @Compare public String firstChar() {
    42.8 +        return "" + ("Hello".toCharArray()[0]);
    42.9 +    }
   42.10 +    
   42.11 +    @Compare public String classCast() {
   42.12 +        Object o = firstChar();
   42.13 +        return String.class.cast(o);
   42.14 +    }
   42.15 +
   42.16 +    @Compare public String classCastThrown() {
   42.17 +        Object o = null;
   42.18 +        return String.class.cast(o);
   42.19 +    }
   42.20 +    
   42.21 +    @Compare public boolean equalToNull() {
   42.22 +        return "Ahoj".equals(null);
   42.23 +    }
   42.24 +    
   42.25      @Compare public static Object compareURLs() throws MalformedURLException {
   42.26          return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   42.27      }
    43.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Tue Jan 15 11:39:15 2013 +0100
    43.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Mon Jan 21 15:57:01 2013 +0100
    43.3 @@ -93,21 +93,12 @@
    43.4      
    43.5      @Compare public int sumTwoDimensions() {
    43.6          int[][] matrix = createMatrix(4, 3);
    43.7 -        int sum = 0;
    43.8 -        for (int i = 0; i < matrix.length; i++) {
    43.9 -            for (int j = 0; j < matrix[i].length; j++) {
   43.10 -                sum += matrix[i][j];
   43.11 -            }
   43.12 -        }
   43.13 -        return sum;
   43.14 +        matrix[0][0] += 10;
   43.15 +        return matrix[0][0];
   43.16      }
   43.17      
   43.18      static int[][] createMatrix(int x, int y) {
   43.19 -        int[][] m = new int[x][y];
   43.20 -        for (int i = 0; i < Math.min(x, y); i++) {
   43.21 -            m[i][i] = i;
   43.22 -        }
   43.23 -        return m;
   43.24 +        return new int[x][y];
   43.25      }
   43.26      
   43.27      @Factory
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionArrayTest.java	Mon Jan 21 15:57:01 2013 +0100
    44.3 @@ -0,0 +1,135 @@
    44.4 +/**
    44.5 + * Back 2 Browser Bytecode Translator
    44.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    44.7 + *
    44.8 + * This program is free software: you can redistribute it and/or modify
    44.9 + * it under the terms of the GNU General Public License as published by
   44.10 + * the Free Software Foundation, version 2 of the License.
   44.11 + *
   44.12 + * This program is distributed in the hope that it will be useful,
   44.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   44.15 + * GNU General Public License for more details.
   44.16 + *
   44.17 + * You should have received a copy of the GNU General Public License
   44.18 + * along with this program. Look for COPYING file in the top folder.
   44.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   44.20 + */
   44.21 +package org.apidesign.bck2brwsr.tck;
   44.22 +
   44.23 +import java.lang.reflect.Array;
   44.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   44.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   44.26 +import org.testng.annotations.Factory;
   44.27 +
   44.28 +/**
   44.29 + *
   44.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   44.31 + */
   44.32 +public class ReflectionArrayTest {
   44.33 +    @Compare public int lengthOfStringArray() {
   44.34 +        String[] arr = (String[]) Array.newInstance(String.class, 10);
   44.35 +        return arr.length;
   44.36 +    }
   44.37 +    
   44.38 +    @Compare public int reflectiveLengthOfStringArray() {
   44.39 +        Object arr = Array.newInstance(String.class, 10);
   44.40 +        return Array.getLength(arr);
   44.41 +    }
   44.42 +
   44.43 +    @Compare public int reflectiveLengthOneNonArray() {
   44.44 +        Object arr = "non-array";
   44.45 +        return Array.getLength(arr);
   44.46 +    }
   44.47 +
   44.48 +    @Compare public String compTypeOfStringArray() {
   44.49 +        String[] arr = (String[]) Array.newInstance(String.class, 10);
   44.50 +        return arr.getClass().getComponentType().getName();
   44.51 +    }
   44.52 +
   44.53 +    @Compare public Object negativeArrayExcp() {
   44.54 +        return Array.newInstance(String.class, -5);
   44.55 +    }
   44.56 +    
   44.57 +    @Compare public int lengthOfIntArray() {
   44.58 +        int[] arr = (int[]) Array.newInstance(Integer.TYPE, 10);
   44.59 +        return arr.length;
   44.60 +    }
   44.61 +
   44.62 +    @Compare public int reflectiveLengthOfIntArray() {
   44.63 +        Object arr = Array.newInstance(Integer.TYPE, 10);
   44.64 +        return Array.getLength(arr);
   44.65 +    }
   44.66 +
   44.67 +    @Compare public String compTypeOfIntArray() {
   44.68 +        int[] arr = (int[]) Array.newInstance(int.class, 10);
   44.69 +        return arr.getClass().getComponentType().getName();
   44.70 +    }
   44.71 +
   44.72 +    @Compare public Object intNegativeArrayExcp() {
   44.73 +        return Array.newInstance(int.class, -5);
   44.74 +    }
   44.75 +
   44.76 +    @Compare public Integer verifyAutobox() {
   44.77 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   44.78 +        return (Integer) Array.get(arr, 0);
   44.79 +    }
   44.80 +    @Compare public String verifyObjectArray() {
   44.81 +        String[] arr = (String[]) Array.newInstance(String.class, 5);
   44.82 +        Array.set(arr, 0, "Hello");
   44.83 +        return (String) Array.get(arr, 0);
   44.84 +    }
   44.85 +    @Compare public int verifyInt() {
   44.86 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   44.87 +        return Array.getInt(arr, 0);
   44.88 +    }
   44.89 +    @Compare public long verifyConvertToLong() {
   44.90 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   44.91 +        return Array.getLong(arr, 0);
   44.92 +    }
   44.93 +
   44.94 +    @Compare public Object verifySetIntToObject() {
   44.95 +        try {
   44.96 +            Object[] arr = (Object[]) Array.newInstance(Object.class, 5);
   44.97 +            Array.setInt(arr, 0, 10);
   44.98 +            return Array.get(arr, 0);
   44.99 +        } catch (Exception exception) {
  44.100 +            return exception.getClass().getName();
  44.101 +        }
  44.102 +    }
  44.103 +    @Compare public long verifySetShort() {
  44.104 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  44.105 +        Array.setShort(arr, 0, (short)10);
  44.106 +        return Array.getLong(arr, 0);
  44.107 +    }
  44.108 +    @Compare public long verifyCantSetLong() {
  44.109 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  44.110 +        Array.setLong(arr, 0, 10);
  44.111 +        return Array.getLong(arr, 0);
  44.112 +    }
  44.113 +    @Compare public float verifyLongToFloat() {
  44.114 +        Object arr = Array.newInstance(float.class, 5);
  44.115 +        Array.setLong(arr, 0, 10);
  44.116 +        return Array.getFloat(arr, 0);
  44.117 +    }
  44.118 +
  44.119 +    @Compare public double verifyConvertToDouble() {
  44.120 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  44.121 +        return Array.getDouble(arr, 0);
  44.122 +    }
  44.123 +    
  44.124 +    @Compare public int multiIntArray() {
  44.125 +        int[][][] arr = (int[][][]) Array.newInstance(int.class, 3, 3, 3);
  44.126 +        return arr[0][1][2] + 5 + arr[2][2][0];
  44.127 +    }
  44.128 +
  44.129 +    @Compare public String multiIntArrayCompType() {
  44.130 +        return Array.newInstance(int.class, 3, 3, 3).getClass().getName();
  44.131 +    }
  44.132 +    
  44.133 +    
  44.134 +    @Factory
  44.135 +    public static Object[] create() {
  44.136 +        return VMTest.create(ReflectionArrayTest.class);
  44.137 +    }
  44.138 +}
    45.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Tue Jan 15 11:39:15 2013 +0100
    45.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Mon Jan 21 15:57:01 2013 +0100
    45.3 @@ -21,6 +21,8 @@
    45.4  import java.util.Arrays;
    45.5  import java.util.Collections;
    45.6  import java.util.List;
    45.7 +import java.util.logging.Level;
    45.8 +import java.util.logging.Logger;
    45.9  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   45.10  import org.apidesign.bck2brwsr.vmtest.Compare;
   45.11  import org.apidesign.bck2brwsr.vmtest.VMTest;
   45.12 @@ -90,6 +92,86 @@
   45.13          return (Integer)plus.invoke(null, 2, 3);
   45.14      }
   45.15      
   45.16 +    @Compare public String classGetNameForByte() {
   45.17 +         return byte.class.getName();
   45.18 +    }
   45.19 +    @Compare public String classGetNameForBaseObject() {
   45.20 +        return newObject().getClass().getName();
   45.21 +    }
   45.22 +    @Compare public String classGetNameForJavaObject() {
   45.23 +        return new Object().getClass().getName();
   45.24 +    }
   45.25 +    @Compare public String classGetNameForObjectArray() {
   45.26 +        return (new Object[3]).getClass().getName();
   45.27 +    }
   45.28 +    @Compare public String classGetNameForSimpleIntArray() {
   45.29 +        return (new int[3]).getClass().getName();
   45.30 +    }
   45.31 +    @Compare public boolean sameClassGetNameForSimpleCharArray() {
   45.32 +        return (new char[3]).getClass() == (new char[34]).getClass();
   45.33 +    }
   45.34 +    @Compare public String classGetNameForMultiIntArray() {
   45.35 +        return (new int[3][4][5][6][7][8][9]).getClass().getName();
   45.36 +    }
   45.37 +    @Compare public String classGetNameForMultiIntArrayInner() {
   45.38 +        final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
   45.39 +        int[][][][][][] subarr = arr[0];
   45.40 +        int[][][][][] subsubarr = subarr[0];
   45.41 +        return subsubarr.getClass().getName();
   45.42 +    }
   45.43 +    @Compare public String classGetNameForMultiStringArray() {
   45.44 +        return (new String[3][4][5][6][7][8][9]).getClass().getName();
   45.45 +    }
   45.46 +    
   45.47 +    @Compare public String classForByte() throws Exception {
   45.48 +        return Class.forName("[Z").getName();
   45.49 +    }
   45.50 +
   45.51 +    @Compare public String classForUnknownArray() {
   45.52 +        try {
   45.53 +            return Class.forName("[W").getName();
   45.54 +        } catch (Exception ex) {
   45.55 +            return ex.getClass().getName();
   45.56 +        }
   45.57 +    }
   45.58 +    
   45.59 +    @Compare public String classForUnknownDeepArray() {
   45.60 +        try {
   45.61 +            return Class.forName("[[[[[W").getName();
   45.62 +        } catch (Exception ex) {
   45.63 +            return ex.getClass().getName();
   45.64 +        }
   45.65 +    }
   45.66 +    
   45.67 +    @Compare public String componentGetNameForObjectArray() {
   45.68 +        return (new Object[3]).getClass().getComponentType().getName();
   45.69 +    }
   45.70 +    @Compare public boolean sameComponentGetNameForObjectArray() {
   45.71 +        return (new Object[3]).getClass().getComponentType() == Object.class;
   45.72 +    }
   45.73 +    @Compare public String componentGetNameForSimpleIntArray() {
   45.74 +        return (new int[3]).getClass().getComponentType().getName();
   45.75 +    }
   45.76 +    @Compare public String componentGetNameForMultiIntArray() {
   45.77 +        return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
   45.78 +    }
   45.79 +    @Compare public String componentGetNameForMultiStringArray() {
   45.80 +        Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
   45.81 +        StringBuilder sb = new StringBuilder();
   45.82 +        for (;;) {
   45.83 +            sb.append(c.getName()).append("\n");
   45.84 +            c = c.getComponentType();
   45.85 +            if (c == null) {
   45.86 +                break;
   45.87 +            }
   45.88 +        }
   45.89 +        return sb.toString();
   45.90 +    }
   45.91 +    
   45.92 +    @Compare public boolean isArray() {
   45.93 +        return new Object[0].getClass().isArray();
   45.94 +    }
   45.95 +    
   45.96      @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
   45.97      private static String[] sort(String[] arr, int len) {
   45.98          List<String> list = Arrays.asList(arr).subList(0, len);
   45.99 @@ -97,6 +179,11 @@
  45.100          return list.toArray(new String[0]);
  45.101      }
  45.102      
  45.103 +    @JavaScriptBody(args = {}, body = "return new Object();")
  45.104 +    private static Object newObject() {
  45.105 +        return new Object();
  45.106 +    }
  45.107 +    
  45.108      @Factory
  45.109      public static Object[] create() {
  45.110          return VMTest.create(ReflectionTest.class);