merge with trunk benchmarks
authorMartin Soch <Martin.Soch@oracle.com>
Wed, 12 Dec 2012 12:41:06 +0100
branchbenchmarks
changeset 309825e468aa4a7
parent 308 bf7dc9e8586c
parent 306 f36b3c273de6
child 311 84c05018e079
merge with trunk
javap/src/main/java/org/apidesign/javap/TypeSignature.java
vm/src/main/java/org/apidesign/vm4brwsr/GenJS.java
vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java
     1.1 --- a/emul/src/main/java/java/lang/Class.java	Wed Dec 12 12:37:41 2012 +0100
     1.2 +++ b/emul/src/main/java/java/lang/Class.java	Wed Dec 12 12:41:06 2012 +0100
     1.3 @@ -25,8 +25,13 @@
     1.4  
     1.5  package java.lang;
     1.6  
     1.7 +import org.apidesign.bck2brwsr.emul.AnnotationImpl;
     1.8  import java.io.InputStream;
     1.9  import java.lang.annotation.Annotation;
    1.10 +import java.lang.reflect.Field;
    1.11 +import java.lang.reflect.Method;
    1.12 +import java.lang.reflect.TypeVariable;
    1.13 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    1.14  
    1.15  /**
    1.16   * Instances of the class {@code Class} represent classes and
    1.17 @@ -74,10 +79,10 @@
    1.18   * @since   JDK1.0
    1.19   */
    1.20  public final
    1.21 -    class Class<T> implements java.io.Serializable {
    1.22 -//                              java.lang.reflect.GenericDeclaration,
    1.23 -//                              java.lang.reflect.Type,
    1.24 -//                              java.lang.reflect.AnnotatedElement {
    1.25 +    class Class<T> implements java.io.Serializable,
    1.26 +                              java.lang.reflect.GenericDeclaration,
    1.27 +                              java.lang.reflect.Type,
    1.28 +                              java.lang.reflect.AnnotatedElement {
    1.29      private static final int ANNOTATION= 0x00002000;
    1.30      private static final int ENUM      = 0x00004000;
    1.31      private static final int SYNTHETIC = 0x00001000;
    1.32 @@ -190,10 +195,15 @@
    1.33       *             </ul>
    1.34       *
    1.35       */
    1.36 +    @JavaScriptBody(args = "self", body =
    1.37 +          "var inst = self.cnstr();"
    1.38 +        + "inst.cons__V(inst);"
    1.39 +        + "return inst;"
    1.40 +    )
    1.41      public T newInstance()
    1.42          throws InstantiationException, IllegalAccessException
    1.43      {
    1.44 -        throw new UnsupportedOperationException("Should be somehow supported");
    1.45 +        throw new UnsupportedOperationException();
    1.46      }
    1.47  
    1.48      /**
    1.49 @@ -273,7 +283,9 @@
    1.50       *          {@code false} otherwise.
    1.51       * @since   JDK1.1
    1.52       */
    1.53 -    public native boolean isArray();
    1.54 +    public boolean isArray() {
    1.55 +        return false;
    1.56 +    }
    1.57  
    1.58  
    1.59      /**
    1.60 @@ -382,13 +394,32 @@
    1.61       *          represented by this object.
    1.62       */
    1.63      public String getName() {
    1.64 -        throw new UnsupportedOperationException();
    1.65 -//        String name = this.name;
    1.66 -//        if (name == null)
    1.67 -//            this.name = name = getName0();
    1.68 -//        return name;
    1.69 +        return jvmName().replace('/', '.');
    1.70      }
    1.71  
    1.72 +    @JavaScriptBody(args = "self", body = "return self.jvmName;")
    1.73 +    private native String jvmName();
    1.74 +
    1.75 +    
    1.76 +    /**
    1.77 +     * Returns an array of {@code TypeVariable} objects that represent the
    1.78 +     * type variables declared by the generic declaration represented by this
    1.79 +     * {@code GenericDeclaration} object, in declaration order.  Returns an
    1.80 +     * array of length 0 if the underlying generic declaration declares no type
    1.81 +     * variables.
    1.82 +     *
    1.83 +     * @return an array of {@code TypeVariable} objects that represent
    1.84 +     *     the type variables declared by this generic declaration
    1.85 +     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
    1.86 +     *     signature of this generic declaration does not conform to
    1.87 +     *     the format specified in
    1.88 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
    1.89 +     * @since 1.5
    1.90 +     */
    1.91 +    public TypeVariable<Class<T>>[] getTypeParameters() {
    1.92 +        throw new UnsupportedOperationException();
    1.93 +    }
    1.94 + 
    1.95      /**
    1.96       * Returns the {@code Class} representing the superclass of the entity
    1.97       * (class, interface, primitive type or void) represented by this
    1.98 @@ -400,6 +431,7 @@
    1.99       *
   1.100       * @return the superclass of the class represented by this object.
   1.101       */
   1.102 +    @JavaScriptBody(args = "self", body = "return self.superclass;")
   1.103      public native Class<? super T> getSuperclass();
   1.104  
   1.105      /**
   1.106 @@ -445,37 +477,282 @@
   1.107       * @since 1.5
   1.108       */
   1.109      public String getSimpleName() {
   1.110 -        throw new UnsupportedOperationException();
   1.111 -////        if (isArray())
   1.112 -////            return getComponentType().getSimpleName()+"[]";
   1.113 -////
   1.114 -////        String simpleName = getSimpleBinaryName();
   1.115 -////        if (simpleName == null) { // top level class
   1.116 -////            simpleName = getName();
   1.117 -////            return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
   1.118 -////        }
   1.119 -////        // According to JLS3 "Binary Compatibility" (13.1) the binary
   1.120 -////        // name of non-package classes (not top level) is the binary
   1.121 -////        // name of the immediately enclosing class followed by a '$' followed by:
   1.122 -////        // (for nested and inner classes): the simple name.
   1.123 -////        // (for local classes): 1 or more digits followed by the simple name.
   1.124 -////        // (for anonymous classes): 1 or more digits.
   1.125 -////
   1.126 -////        // Since getSimpleBinaryName() will strip the binary name of
   1.127 -////        // the immediatly enclosing class, we are now looking at a
   1.128 -////        // string that matches the regular expression "\$[0-9]*"
   1.129 -////        // followed by a simple name (considering the simple of an
   1.130 -////        // anonymous class to be the empty string).
   1.131 -////
   1.132 -////        // Remove leading "\$[0-9]*" from the name
   1.133 -////        int length = simpleName.length();
   1.134 -////        if (length < 1 || simpleName.charAt(0) != '$')
   1.135 -////            throw new InternalError("Malformed class name");
   1.136 -////        int index = 1;
   1.137 -////        while (index < length && isAsciiDigit(simpleName.charAt(index)))
   1.138 -////            index++;
   1.139 -////        // Eventually, this is the empty string iff this is an anonymous class
   1.140 -////        return simpleName.substring(index);
   1.141 +        if (isArray())
   1.142 +            return getComponentType().getSimpleName()+"[]";
   1.143 +
   1.144 +        String simpleName = getSimpleBinaryName();
   1.145 +        if (simpleName == null) { // top level class
   1.146 +            simpleName = getName();
   1.147 +            return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
   1.148 +        }
   1.149 +        // According to JLS3 "Binary Compatibility" (13.1) the binary
   1.150 +        // name of non-package classes (not top level) is the binary
   1.151 +        // name of the immediately enclosing class followed by a '$' followed by:
   1.152 +        // (for nested and inner classes): the simple name.
   1.153 +        // (for local classes): 1 or more digits followed by the simple name.
   1.154 +        // (for anonymous classes): 1 or more digits.
   1.155 +
   1.156 +        // Since getSimpleBinaryName() will strip the binary name of
   1.157 +        // the immediatly enclosing class, we are now looking at a
   1.158 +        // string that matches the regular expression "\$[0-9]*"
   1.159 +        // followed by a simple name (considering the simple of an
   1.160 +        // anonymous class to be the empty string).
   1.161 +
   1.162 +        // Remove leading "\$[0-9]*" from the name
   1.163 +        int length = simpleName.length();
   1.164 +        if (length < 1 || simpleName.charAt(0) != '$')
   1.165 +            throw new IllegalStateException("Malformed class name");
   1.166 +        int index = 1;
   1.167 +        while (index < length && isAsciiDigit(simpleName.charAt(index)))
   1.168 +            index++;
   1.169 +        // Eventually, this is the empty string iff this is an anonymous class
   1.170 +        return simpleName.substring(index);
   1.171 +    }
   1.172 +
   1.173 +    /**
   1.174 +     * Returns the "simple binary name" of the underlying class, i.e.,
   1.175 +     * the binary name without the leading enclosing class name.
   1.176 +     * Returns {@code null} if the underlying class is a top level
   1.177 +     * class.
   1.178 +     */
   1.179 +    private String getSimpleBinaryName() {
   1.180 +        Class<?> enclosingClass = null; // XXX getEnclosingClass();
   1.181 +        if (enclosingClass == null) // top level class
   1.182 +            return null;
   1.183 +        // Otherwise, strip the enclosing class' name
   1.184 +        try {
   1.185 +            return getName().substring(enclosingClass.getName().length());
   1.186 +        } catch (IndexOutOfBoundsException ex) {
   1.187 +            throw new IllegalStateException("Malformed class name");
   1.188 +        }
   1.189 +    }
   1.190 +
   1.191 +    /**
   1.192 +     * Returns an array containing {@code Field} objects reflecting all
   1.193 +     * the accessible public fields of the class or interface represented by
   1.194 +     * this {@code Class} object.  The elements in the array returned are
   1.195 +     * not sorted and are not in any particular order.  This method returns an
   1.196 +     * array of length 0 if the class or interface has no accessible public
   1.197 +     * fields, or if it represents an array class, a primitive type, or void.
   1.198 +     *
   1.199 +     * <p> Specifically, if this {@code Class} object represents a class,
   1.200 +     * this method returns the public fields of this class and of all its
   1.201 +     * superclasses.  If this {@code Class} object represents an
   1.202 +     * interface, this method returns the fields of this interface and of all
   1.203 +     * its superinterfaces.
   1.204 +     *
   1.205 +     * <p> The implicit length field for array class is not reflected by this
   1.206 +     * method. User code should use the methods of class {@code Array} to
   1.207 +     * manipulate arrays.
   1.208 +     *
   1.209 +     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
   1.210 +     *
   1.211 +     * @return the array of {@code Field} objects representing the
   1.212 +     * public fields
   1.213 +     * @exception  SecurityException
   1.214 +     *             If a security manager, <i>s</i>, is present and any of the
   1.215 +     *             following conditions is met:
   1.216 +     *
   1.217 +     *             <ul>
   1.218 +     *
   1.219 +     *             <li> invocation of
   1.220 +     *             {@link SecurityManager#checkMemberAccess
   1.221 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   1.222 +     *             access to the fields within this class
   1.223 +     *
   1.224 +     *             <li> the caller's class loader is not the same as or an
   1.225 +     *             ancestor of the class loader for the current class and
   1.226 +     *             invocation of {@link SecurityManager#checkPackageAccess
   1.227 +     *             s.checkPackageAccess()} denies access to the package
   1.228 +     *             of this class
   1.229 +     *
   1.230 +     *             </ul>
   1.231 +     *
   1.232 +     * @since JDK1.1
   1.233 +     */
   1.234 +    public Field[] getFields() throws SecurityException {
   1.235 +        throw new SecurityException();
   1.236 +    }
   1.237 +
   1.238 +    /**
   1.239 +     * Returns an array containing {@code Method} objects reflecting all
   1.240 +     * the public <em>member</em> methods of the class or interface represented
   1.241 +     * by this {@code Class} object, including those declared by the class
   1.242 +     * or interface and those inherited from superclasses and
   1.243 +     * superinterfaces.  Array classes return all the (public) member methods
   1.244 +     * inherited from the {@code Object} class.  The elements in the array
   1.245 +     * returned are not sorted and are not in any particular order.  This
   1.246 +     * method returns an array of length 0 if this {@code Class} object
   1.247 +     * represents a class or interface that has no public member methods, or if
   1.248 +     * this {@code Class} object represents a primitive type or void.
   1.249 +     *
   1.250 +     * <p> The class initialization method {@code <clinit>} is not
   1.251 +     * included in the returned array. If the class declares multiple public
   1.252 +     * member methods with the same parameter types, they are all included in
   1.253 +     * the returned array.
   1.254 +     *
   1.255 +     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
   1.256 +     *
   1.257 +     * @return the array of {@code Method} objects representing the
   1.258 +     * public methods of this class
   1.259 +     * @exception  SecurityException
   1.260 +     *             If a security manager, <i>s</i>, is present and any of the
   1.261 +     *             following conditions is met:
   1.262 +     *
   1.263 +     *             <ul>
   1.264 +     *
   1.265 +     *             <li> invocation of
   1.266 +     *             {@link SecurityManager#checkMemberAccess
   1.267 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   1.268 +     *             access to the methods within this class
   1.269 +     *
   1.270 +     *             <li> the caller's class loader is not the same as or an
   1.271 +     *             ancestor of the class loader for the current class and
   1.272 +     *             invocation of {@link SecurityManager#checkPackageAccess
   1.273 +     *             s.checkPackageAccess()} denies access to the package
   1.274 +     *             of this class
   1.275 +     *
   1.276 +     *             </ul>
   1.277 +     *
   1.278 +     * @since JDK1.1
   1.279 +     */
   1.280 +    public Method[] getMethods() throws SecurityException {
   1.281 +        return Method.findMethods(this);
   1.282 +    }
   1.283 +
   1.284 +    /**
   1.285 +     * Returns a {@code Field} object that reflects the specified public
   1.286 +     * member field of the class or interface represented by this
   1.287 +     * {@code Class} object. The {@code name} parameter is a
   1.288 +     * {@code String} specifying the simple name of the desired field.
   1.289 +     *
   1.290 +     * <p> The field to be reflected is determined by the algorithm that
   1.291 +     * follows.  Let C be the class represented by this object:
   1.292 +     * <OL>
   1.293 +     * <LI> If C declares a public field with the name specified, that is the
   1.294 +     *      field to be reflected.</LI>
   1.295 +     * <LI> If no field was found in step 1 above, this algorithm is applied
   1.296 +     *      recursively to each direct superinterface of C. The direct
   1.297 +     *      superinterfaces are searched in the order they were declared.</LI>
   1.298 +     * <LI> If no field was found in steps 1 and 2 above, and C has a
   1.299 +     *      superclass S, then this algorithm is invoked recursively upon S.
   1.300 +     *      If C has no superclass, then a {@code NoSuchFieldException}
   1.301 +     *      is thrown.</LI>
   1.302 +     * </OL>
   1.303 +     *
   1.304 +     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
   1.305 +     *
   1.306 +     * @param name the field name
   1.307 +     * @return  the {@code Field} object of this class specified by
   1.308 +     * {@code name}
   1.309 +     * @exception NoSuchFieldException if a field with the specified name is
   1.310 +     *              not found.
   1.311 +     * @exception NullPointerException if {@code name} is {@code null}
   1.312 +     * @exception  SecurityException
   1.313 +     *             If a security manager, <i>s</i>, is present and any of the
   1.314 +     *             following conditions is met:
   1.315 +     *
   1.316 +     *             <ul>
   1.317 +     *
   1.318 +     *             <li> invocation of
   1.319 +     *             {@link SecurityManager#checkMemberAccess
   1.320 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   1.321 +     *             access to the field
   1.322 +     *
   1.323 +     *             <li> the caller's class loader is not the same as or an
   1.324 +     *             ancestor of the class loader for the current class and
   1.325 +     *             invocation of {@link SecurityManager#checkPackageAccess
   1.326 +     *             s.checkPackageAccess()} denies access to the package
   1.327 +     *             of this class
   1.328 +     *
   1.329 +     *             </ul>
   1.330 +     *
   1.331 +     * @since JDK1.1
   1.332 +     */
   1.333 +    public Field getField(String name)
   1.334 +        throws SecurityException {
   1.335 +        throw new SecurityException();
   1.336 +    }
   1.337 +    
   1.338 +    
   1.339 +    /**
   1.340 +     * Returns a {@code Method} object that reflects the specified public
   1.341 +     * member method of the class or interface represented by this
   1.342 +     * {@code Class} object. The {@code name} parameter is a
   1.343 +     * {@code String} specifying the simple name of the desired method. The
   1.344 +     * {@code parameterTypes} parameter is an array of {@code Class}
   1.345 +     * objects that identify the method's formal parameter types, in declared
   1.346 +     * order. If {@code parameterTypes} is {@code null}, it is
   1.347 +     * treated as if it were an empty array.
   1.348 +     *
   1.349 +     * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
   1.350 +     * {@code NoSuchMethodException} is raised. Otherwise, the method to
   1.351 +     * be reflected is determined by the algorithm that follows.  Let C be the
   1.352 +     * class represented by this object:
   1.353 +     * <OL>
   1.354 +     * <LI> C is searched for any <I>matching methods</I>. If no matching
   1.355 +     *      method is found, the algorithm of step 1 is invoked recursively on
   1.356 +     *      the superclass of C.</LI>
   1.357 +     * <LI> If no method was found in step 1 above, the superinterfaces of C
   1.358 +     *      are searched for a matching method. If any such method is found, it
   1.359 +     *      is reflected.</LI>
   1.360 +     * </OL>
   1.361 +     *
   1.362 +     * To find a matching method in a class C:&nbsp; If C declares exactly one
   1.363 +     * public method with the specified name and exactly the same formal
   1.364 +     * parameter types, that is the method reflected. If more than one such
   1.365 +     * method is found in C, and one of these methods has a return type that is
   1.366 +     * more specific than any of the others, that method is reflected;
   1.367 +     * otherwise one of the methods is chosen arbitrarily.
   1.368 +     *
   1.369 +     * <p>Note that there may be more than one matching method in a
   1.370 +     * class because while the Java language forbids a class to
   1.371 +     * declare multiple methods with the same signature but different
   1.372 +     * return types, the Java virtual machine does not.  This
   1.373 +     * increased flexibility in the virtual machine can be used to
   1.374 +     * implement various language features.  For example, covariant
   1.375 +     * returns can be implemented with {@linkplain
   1.376 +     * java.lang.reflect.Method#isBridge bridge methods}; the bridge
   1.377 +     * method and the method being overridden would have the same
   1.378 +     * signature but different return types.
   1.379 +     *
   1.380 +     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
   1.381 +     *
   1.382 +     * @param name the name of the method
   1.383 +     * @param parameterTypes the list of parameters
   1.384 +     * @return the {@code Method} object that matches the specified
   1.385 +     * {@code name} and {@code parameterTypes}
   1.386 +     * @exception NoSuchMethodException if a matching method is not found
   1.387 +     *            or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
   1.388 +     * @exception NullPointerException if {@code name} is {@code null}
   1.389 +     * @exception  SecurityException
   1.390 +     *             If a security manager, <i>s</i>, is present and any of the
   1.391 +     *             following conditions is met:
   1.392 +     *
   1.393 +     *             <ul>
   1.394 +     *
   1.395 +     *             <li> invocation of
   1.396 +     *             {@link SecurityManager#checkMemberAccess
   1.397 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   1.398 +     *             access to the method
   1.399 +     *
   1.400 +     *             <li> the caller's class loader is not the same as or an
   1.401 +     *             ancestor of the class loader for the current class and
   1.402 +     *             invocation of {@link SecurityManager#checkPackageAccess
   1.403 +     *             s.checkPackageAccess()} denies access to the package
   1.404 +     *             of this class
   1.405 +     *
   1.406 +     *             </ul>
   1.407 +     *
   1.408 +     * @since JDK1.1
   1.409 +     */
   1.410 +    public Method getMethod(String name, Class<?>... parameterTypes)
   1.411 +        throws SecurityException {
   1.412 +        Method m = Method.findMethod(this, name, parameterTypes);
   1.413 +        if (m == null) {
   1.414 +            throw new SecurityException(); // XXX: NoSuchMethodException
   1.415 +        }
   1.416 +        return m;
   1.417      }
   1.418  
   1.419      /**
   1.420 @@ -497,25 +774,25 @@
   1.421       * @since 1.5
   1.422       */
   1.423      public String getCanonicalName() {
   1.424 -        throw new UnsupportedOperationException();
   1.425 -//        if (isArray()) {
   1.426 -//            String canonicalName = getComponentType().getCanonicalName();
   1.427 -//            if (canonicalName != null)
   1.428 -//                return canonicalName + "[]";
   1.429 -//            else
   1.430 -//                return null;
   1.431 -//        }
   1.432 +        if (isArray()) {
   1.433 +            String canonicalName = getComponentType().getCanonicalName();
   1.434 +            if (canonicalName != null)
   1.435 +                return canonicalName + "[]";
   1.436 +            else
   1.437 +                return null;
   1.438 +        }
   1.439  //        if (isLocalOrAnonymousClass())
   1.440  //            return null;
   1.441  //        Class<?> enclosingClass = getEnclosingClass();
   1.442 -//        if (enclosingClass == null) { // top level class
   1.443 -//            return getName();
   1.444 -//        } else {
   1.445 -//            String enclosingName = enclosingClass.getCanonicalName();
   1.446 -//            if (enclosingName == null)
   1.447 -//                return null;
   1.448 -//            return enclosingName + "." + getSimpleName();
   1.449 -//        }
   1.450 +        Class<?> enclosingClass = null;
   1.451 +        if (enclosingClass == null) { // top level class
   1.452 +            return getName();
   1.453 +        } else {
   1.454 +            String enclosingName = enclosingClass.getCanonicalName();
   1.455 +            if (enclosingName == null)
   1.456 +                return null;
   1.457 +            return enclosingName + "." + getSimpleName();
   1.458 +        }
   1.459      }
   1.460  
   1.461      /**
   1.462 @@ -676,7 +953,9 @@
   1.463       * @see     java.lang.reflect.Array
   1.464       * @since JDK1.1
   1.465       */
   1.466 -    public native Class<?> getComponentType();
   1.467 +    public Class<?> getComponentType() {
   1.468 +        return null;
   1.469 +    }
   1.470  
   1.471      /**
   1.472       * Returns true if and only if this class was declared as an enum in the
   1.473 @@ -743,18 +1022,32 @@
   1.474              throw new ClassCastException(this.toString());
   1.475      }
   1.476  
   1.477 +    @JavaScriptBody(args = { "self", "ac" }, 
   1.478 +        body = 
   1.479 +          "if (self.anno) {"
   1.480 +        + "  return self.anno['L' + ac.jvmName + ';'];"
   1.481 +        + "} else return null;"
   1.482 +    )
   1.483 +    private Object getAnnotationData(Class<?> annotationClass) {
   1.484 +        throw new UnsupportedOperationException();
   1.485 +    }
   1.486      /**
   1.487       * @throws NullPointerException {@inheritDoc}
   1.488       * @since 1.5
   1.489       */
   1.490      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
   1.491 -        throw new UnsupportedOperationException();
   1.492 +        Object data = getAnnotationData(annotationClass);
   1.493 +        return data == null ? null : AnnotationImpl.create(annotationClass, data);
   1.494      }
   1.495  
   1.496      /**
   1.497       * @throws NullPointerException {@inheritDoc}
   1.498       * @since 1.5
   1.499       */
   1.500 +    @JavaScriptBody(args = { "self", "ac" }, 
   1.501 +        body = "if (self.anno && self.anno['L' + ac.jvmName + ';']) { return true; }"
   1.502 +        + "else return false;"
   1.503 +    )
   1.504      public boolean isAnnotationPresent(
   1.505          Class<? extends Annotation> annotationClass) {
   1.506          if (annotationClass == null)
   1.507 @@ -763,12 +1056,17 @@
   1.508          return getAnnotation(annotationClass) != null;
   1.509      }
   1.510  
   1.511 +    @JavaScriptBody(args = "self", body = "return self.anno;")
   1.512 +    private Object getAnnotationData() {
   1.513 +        throw new UnsupportedOperationException();
   1.514 +    }
   1.515  
   1.516      /**
   1.517       * @since 1.5
   1.518       */
   1.519      public Annotation[] getAnnotations() {
   1.520 -        throw new UnsupportedOperationException();
   1.521 +        Object data = getAnnotationData();
   1.522 +        return data == null ? new Annotation[0] : AnnotationImpl.create(data);
   1.523      }
   1.524  
   1.525      /**
     2.1 --- a/emul/src/main/java/java/lang/Object.java	Wed Dec 12 12:37:41 2012 +0100
     2.2 +++ b/emul/src/main/java/java/lang/Object.java	Wed Dec 12 12:41:06 2012 +0100
     2.3 @@ -66,6 +66,7 @@
     2.4       * @see    Class Literals, section 15.8.2 of
     2.5       *         <cite>The Java&trade; Language Specification</cite>.
     2.6       */
     2.7 +    @JavaScriptBody(args="self", body="return self.constructor.$class;")
     2.8      public final native Class<?> getClass();
     2.9  
    2.10      /**
     3.1 --- a/emul/src/main/java/java/lang/String.java	Wed Dec 12 12:37:41 2012 +0100
     3.2 +++ b/emul/src/main/java/java/lang/String.java	Wed Dec 12 12:41:06 2012 +0100
     3.3 @@ -1426,7 +1426,7 @@
     3.4       */
     3.5      @JavaScriptBody(args = { "self", "find", "from" }, body=
     3.6          "find = find.toString();\n" +
     3.7 -        "return self.toString().substring(from, find.length) === find;\n"
     3.8 +        "return self.toString().substring(from, from + find.length) === find;\n"
     3.9      )
    3.10      public boolean startsWith(String prefix, int toffset) {
    3.11          char ta[] = toCharArray();
    3.12 @@ -1691,6 +1691,10 @@
    3.13       *          than or equal to <code>fromIndex</code>, or <code>-1</code>
    3.14       *          if the character does not occur before that point.
    3.15       */
    3.16 +    @JavaScriptBody(args = { "self", "ch", "from" }, body = 
    3.17 +        "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
    3.18 +        "return self.toString().lastIndexOf(ch, from);"
    3.19 +    )
    3.20      public int lastIndexOf(int ch, int fromIndex) {
    3.21          if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
    3.22              // handle most cases here (ch is a BMP code point or a
    3.23 @@ -1763,7 +1767,7 @@
    3.24       *          or {@code -1} if there is no such occurrence.
    3.25       */
    3.26      @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
    3.27 -        "return self.toString().indexOf(str.toString(), fromIndex) >= 0;"
    3.28 +        "return self.toString().indexOf(str.toString(), fromIndex);"
    3.29      )
    3.30      public int indexOf(String str, int fromIndex) {
    3.31          return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
    3.32 @@ -1855,6 +1859,9 @@
    3.33       *          searching backward from the specified index,
    3.34       *          or {@code -1} if there is no such occurrence.
    3.35       */
    3.36 +    @JavaScriptBody(args = { "self", "s", "from" }, body = 
    3.37 +        "return self.toString().lastIndexOf(s.toString(), from);"
    3.38 +    )
    3.39      public int lastIndexOf(String str, int fromIndex) {
    3.40          return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
    3.41      }
     4.1 --- a/emul/src/main/java/java/lang/Throwable.java	Wed Dec 12 12:37:41 2012 +0100
     4.2 +++ b/emul/src/main/java/java/lang/Throwable.java	Wed Dec 12 12:41:06 2012 +0100
     4.3 @@ -25,6 +25,7 @@
     4.4  
     4.5  package java.lang;
     4.6  import  java.io.*;
     4.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     4.8  
     4.9  /**
    4.10   * The {@code Throwable} class is the superclass of all errors and
    4.11 @@ -782,6 +783,7 @@
    4.12          return this;
    4.13      }
    4.14  
    4.15 +    @JavaScriptBody(args = { "self", "dummy" }, body = "")
    4.16      private native Throwable fillInStackTrace(int dummy);
    4.17  
    4.18      /**
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/emul/src/main/java/java/lang/reflect/AccessibleObject.java	Wed Dec 12 12:41:06 2012 +0100
     5.3 @@ -0,0 +1,167 @@
     5.4 +/*
     5.5 + * Copyright (c) 1997, 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.reflect;
    5.30 +
    5.31 +import java.lang.annotation.Annotation;
    5.32 +
    5.33 +/**
    5.34 + * The AccessibleObject class is the base class for Field, Method and
    5.35 + * Constructor objects.  It provides the ability to flag a reflected
    5.36 + * object as suppressing default Java language access control checks
    5.37 + * when it is used.  The access checks--for public, default (package)
    5.38 + * access, protected, and private members--are performed when Fields,
    5.39 + * Methods or Constructors are used to set or get fields, to invoke
    5.40 + * methods, or to create and initialize new instances of classes,
    5.41 + * respectively.
    5.42 + *
    5.43 + * <p>Setting the {@code accessible} flag in a reflected object
    5.44 + * permits sophisticated applications with sufficient privilege, such
    5.45 + * as Java Object Serialization or other persistence mechanisms, to
    5.46 + * manipulate objects in a manner that would normally be prohibited.
    5.47 + *
    5.48 + * <p>By default, a reflected object is <em>not</em> accessible.
    5.49 + *
    5.50 + * @see Field
    5.51 + * @see Method
    5.52 + * @see Constructor
    5.53 + * @see ReflectPermission
    5.54 + *
    5.55 + * @since 1.2
    5.56 + */
    5.57 +public class AccessibleObject implements AnnotatedElement {
    5.58 +
    5.59 +    /**
    5.60 +     * Convenience method to set the {@code accessible} flag for an
    5.61 +     * array of objects with a single security check (for efficiency).
    5.62 +     *
    5.63 +     * <p>First, if there is a security manager, its
    5.64 +     * {@code checkPermission} method is called with a
    5.65 +     * {@code ReflectPermission("suppressAccessChecks")} permission.
    5.66 +     *
    5.67 +     * <p>A {@code SecurityException} is raised if {@code flag} is
    5.68 +     * {@code true} but accessibility of any of the elements of the input
    5.69 +     * {@code array} may not be changed (for example, if the element
    5.70 +     * object is a {@link Constructor} object for the class {@link
    5.71 +     * java.lang.Class}).  In the event of such a SecurityException, the
    5.72 +     * accessibility of objects is set to {@code flag} for array elements
    5.73 +     * upto (and excluding) the element for which the exception occurred; the
    5.74 +     * accessibility of elements beyond (and including) the element for which
    5.75 +     * the exception occurred is unchanged.
    5.76 +     *
    5.77 +     * @param array the array of AccessibleObjects
    5.78 +     * @param flag  the new value for the {@code accessible} flag
    5.79 +     *              in each object
    5.80 +     * @throws SecurityException if the request is denied.
    5.81 +     * @see SecurityManager#checkPermission
    5.82 +     * @see java.lang.RuntimePermission
    5.83 +     */
    5.84 +    public static void setAccessible(AccessibleObject[] array, boolean flag)
    5.85 +        throws SecurityException {
    5.86 +        throw new SecurityException();
    5.87 +    }
    5.88 +
    5.89 +    /**
    5.90 +     * Set the {@code accessible} flag for this object to
    5.91 +     * the indicated boolean value.  A value of {@code true} indicates that
    5.92 +     * the reflected object should suppress Java language access
    5.93 +     * checking when it is used.  A value of {@code false} indicates
    5.94 +     * that the reflected object should enforce Java language access checks.
    5.95 +     *
    5.96 +     * <p>First, if there is a security manager, its
    5.97 +     * {@code checkPermission} method is called with a
    5.98 +     * {@code ReflectPermission("suppressAccessChecks")} permission.
    5.99 +     *
   5.100 +     * <p>A {@code SecurityException} is raised if {@code flag} is
   5.101 +     * {@code true} but accessibility of this object may not be changed
   5.102 +     * (for example, if this element object is a {@link Constructor} object for
   5.103 +     * the class {@link java.lang.Class}).
   5.104 +     *
   5.105 +     * <p>A {@code SecurityException} is raised if this object is a {@link
   5.106 +     * java.lang.reflect.Constructor} object for the class
   5.107 +     * {@code java.lang.Class}, and {@code flag} is true.
   5.108 +     *
   5.109 +     * @param flag the new value for the {@code accessible} flag
   5.110 +     * @throws SecurityException if the request is denied.
   5.111 +     * @see SecurityManager#checkPermission
   5.112 +     * @see java.lang.RuntimePermission
   5.113 +     */
   5.114 +    public void setAccessible(boolean flag) throws SecurityException {
   5.115 +        throw new SecurityException();
   5.116 +    }
   5.117 +
   5.118 +    /**
   5.119 +     * Get the value of the {@code accessible} flag for this object.
   5.120 +     *
   5.121 +     * @return the value of the object's {@code accessible} flag
   5.122 +     */
   5.123 +    public boolean isAccessible() {
   5.124 +        return override;
   5.125 +    }
   5.126 +
   5.127 +    /**
   5.128 +     * Constructor: only used by the Java Virtual Machine.
   5.129 +     */
   5.130 +    protected AccessibleObject() {}
   5.131 +
   5.132 +    // Indicates whether language-level access checks are overridden
   5.133 +    // by this object. Initializes to "false". This field is used by
   5.134 +    // Field, Method, and Constructor.
   5.135 +    //
   5.136 +    // NOTE: for security purposes, this field must not be visible
   5.137 +    // outside this package.
   5.138 +    boolean override;
   5.139 +
   5.140 +    /**
   5.141 +     * @throws NullPointerException {@inheritDoc}
   5.142 +     * @since 1.5
   5.143 +     */
   5.144 +    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   5.145 +        throw new AssertionError("All subclasses should override this method");
   5.146 +    }
   5.147 +
   5.148 +    /**
   5.149 +     * @throws NullPointerException {@inheritDoc}
   5.150 +     * @since 1.5
   5.151 +     */
   5.152 +    public boolean isAnnotationPresent(
   5.153 +        Class<? extends Annotation> annotationClass) {
   5.154 +        return getAnnotation(annotationClass) != null;
   5.155 +    }
   5.156 +
   5.157 +    /**
   5.158 +     * @since 1.5
   5.159 +     */
   5.160 +    public Annotation[] getAnnotations() {
   5.161 +        return getDeclaredAnnotations();
   5.162 +    }
   5.163 +
   5.164 +    /**
   5.165 +     * @since 1.5
   5.166 +     */
   5.167 +    public Annotation[] getDeclaredAnnotations()  {
   5.168 +        throw new AssertionError("All subclasses should override this method");
   5.169 +    }
   5.170 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/emul/src/main/java/java/lang/reflect/AnnotatedElement.java	Wed Dec 12 12:41:06 2012 +0100
     6.3 @@ -0,0 +1,112 @@
     6.4 +/*
     6.5 + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Oracle designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Oracle in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 + * or visit www.oracle.com if you need additional information or have any
    6.26 + * questions.
    6.27 + */
    6.28 +
    6.29 +package java.lang.reflect;
    6.30 +
    6.31 +import java.lang.annotation.Annotation;
    6.32 +
    6.33 +/**
    6.34 + * Represents an annotated element of the program currently running in this
    6.35 + * VM.  This interface allows annotations to be read reflectively.  All
    6.36 + * annotations returned by methods in this interface are immutable and
    6.37 + * serializable.  It is permissible for the caller to modify the
    6.38 + * arrays returned by accessors for array-valued enum members; it will
    6.39 + * have no affect on the arrays returned to other callers.
    6.40 + *
    6.41 + * <p>If an annotation returned by a method in this interface contains
    6.42 + * (directly or indirectly) a {@link Class}-valued member referring to
    6.43 + * a class that is not accessible in this VM, attempting to read the class
    6.44 + * by calling the relevant Class-returning method on the returned annotation
    6.45 + * will result in a {@link TypeNotPresentException}.
    6.46 + *
    6.47 + * <p>Similarly, attempting to read an enum-valued member will result in
    6.48 + * a {@link EnumConstantNotPresentException} if the enum constant in the
    6.49 + * annotation is no longer present in the enum type.
    6.50 + *
    6.51 + * <p>Finally, Attempting to read a member whose definition has evolved
    6.52 + * incompatibly will result in a {@link
    6.53 + * java.lang.annotation.AnnotationTypeMismatchException} or an
    6.54 + * {@link java.lang.annotation.IncompleteAnnotationException}.
    6.55 + *
    6.56 + * @see java.lang.EnumConstantNotPresentException
    6.57 + * @see java.lang.TypeNotPresentException
    6.58 + * @see java.lang.annotation.AnnotationFormatError
    6.59 + * @see java.lang.annotation.AnnotationTypeMismatchException
    6.60 + * @see java.lang.annotation.IncompleteAnnotationException
    6.61 + * @since 1.5
    6.62 + * @author Josh Bloch
    6.63 + */
    6.64 +public interface AnnotatedElement {
    6.65 +    /**
    6.66 +     * Returns true if an annotation for the specified type
    6.67 +     * is present on this element, else false.  This method
    6.68 +     * is designed primarily for convenient access to marker annotations.
    6.69 +     *
    6.70 +     * @param annotationClass the Class object corresponding to the
    6.71 +     *        annotation type
    6.72 +     * @return true if an annotation for the specified annotation
    6.73 +     *     type is present on this element, else false
    6.74 +     * @throws NullPointerException if the given annotation class is null
    6.75 +     * @since 1.5
    6.76 +     */
    6.77 +     boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
    6.78 +
    6.79 +   /**
    6.80 +     * Returns this element's annotation for the specified type if
    6.81 +     * such an annotation is present, else null.
    6.82 +     *
    6.83 +     * @param annotationClass the Class object corresponding to the
    6.84 +     *        annotation type
    6.85 +     * @return this element's annotation for the specified annotation type if
    6.86 +     *     present on this element, else null
    6.87 +     * @throws NullPointerException if the given annotation class is null
    6.88 +     * @since 1.5
    6.89 +     */
    6.90 +    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
    6.91 +
    6.92 +    /**
    6.93 +     * Returns all annotations present on this element.  (Returns an array
    6.94 +     * of length zero if this element has no annotations.)  The caller of
    6.95 +     * this method is free to modify the returned array; it will have no
    6.96 +     * effect on the arrays returned to other callers.
    6.97 +     *
    6.98 +     * @return all annotations present on this element
    6.99 +     * @since 1.5
   6.100 +     */
   6.101 +    Annotation[] getAnnotations();
   6.102 +
   6.103 +    /**
   6.104 +     * Returns all annotations that are directly present on this
   6.105 +     * element.  Unlike the other methods in this interface, this method
   6.106 +     * ignores inherited annotations.  (Returns an array of length zero if
   6.107 +     * no annotations are directly present on this element.)  The caller of
   6.108 +     * this method is free to modify the returned array; it will have no
   6.109 +     * effect on the arrays returned to other callers.
   6.110 +     *
   6.111 +     * @return All annotations directly present on this element
   6.112 +     * @since 1.5
   6.113 +     */
   6.114 +    Annotation[] getDeclaredAnnotations();
   6.115 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/emul/src/main/java/java/lang/reflect/Field.java	Wed Dec 12 12:41:06 2012 +0100
     7.3 @@ -0,0 +1,953 @@
     7.4 +/*
     7.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Oracle designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Oracle in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 + * or visit www.oracle.com if you need additional information or have any
    7.26 + * questions.
    7.27 + */
    7.28 +
    7.29 +package java.lang.reflect;
    7.30 +
    7.31 +import java.lang.annotation.Annotation;
    7.32 +
    7.33 +
    7.34 +/**
    7.35 + * A {@code Field} provides information about, and dynamic access to, a
    7.36 + * single field of a class or an interface.  The reflected field may
    7.37 + * be a class (static) field or an instance field.
    7.38 + *
    7.39 + * <p>A {@code Field} permits widening conversions to occur during a get or
    7.40 + * set access operation, but throws an {@code IllegalArgumentException} if a
    7.41 + * narrowing conversion would occur.
    7.42 + *
    7.43 + * @see Member
    7.44 + * @see java.lang.Class
    7.45 + * @see java.lang.Class#getFields()
    7.46 + * @see java.lang.Class#getField(String)
    7.47 + * @see java.lang.Class#getDeclaredFields()
    7.48 + * @see java.lang.Class#getDeclaredField(String)
    7.49 + *
    7.50 + * @author Kenneth Russell
    7.51 + * @author Nakul Saraiya
    7.52 + */
    7.53 +public final
    7.54 +class Field extends AccessibleObject implements Member {
    7.55 +
    7.56 +    private Class<?>            clazz;
    7.57 +    private int                 slot;
    7.58 +    // This is guaranteed to be interned by the VM in the 1.4
    7.59 +    // reflection implementation
    7.60 +    private String              name;
    7.61 +    private Class<?>            type;
    7.62 +    private int                 modifiers;
    7.63 +    // Generics and annotations support
    7.64 +    private transient String    signature;
    7.65 +    private byte[]              annotations;
    7.66 +    // For sharing of FieldAccessors. This branching structure is
    7.67 +    // currently only two levels deep (i.e., one root Field and
    7.68 +    // potentially many Field objects pointing to it.)
    7.69 +    private Field               root;
    7.70 +
    7.71 +    // Generics infrastructure
    7.72 +
    7.73 +    private String getGenericSignature() {return signature;}
    7.74 +
    7.75 +
    7.76 +    /**
    7.77 +     * Package-private constructor used by ReflectAccess to enable
    7.78 +     * instantiation of these objects in Java code from the java.lang
    7.79 +     * package via sun.reflect.LangReflectAccess.
    7.80 +     */
    7.81 +    Field(Class<?> declaringClass,
    7.82 +          String name,
    7.83 +          Class<?> type,
    7.84 +          int modifiers,
    7.85 +          int slot,
    7.86 +          String signature,
    7.87 +          byte[] annotations)
    7.88 +    {
    7.89 +        this.clazz = declaringClass;
    7.90 +        this.name = name;
    7.91 +        this.type = type;
    7.92 +        this.modifiers = modifiers;
    7.93 +        this.slot = slot;
    7.94 +        this.signature = signature;
    7.95 +        this.annotations = annotations;
    7.96 +    }
    7.97 +
    7.98 +    /**
    7.99 +     * Package-private routine (exposed to java.lang.Class via
   7.100 +     * ReflectAccess) which returns a copy of this Field. The copy's
   7.101 +     * "root" field points to this Field.
   7.102 +     */
   7.103 +    Field copy() {
   7.104 +        // This routine enables sharing of FieldAccessor objects
   7.105 +        // among Field objects which refer to the same underlying
   7.106 +        // method in the VM. (All of this contortion is only necessary
   7.107 +        // because of the "accessibility" bit in AccessibleObject,
   7.108 +        // which implicitly requires that new java.lang.reflect
   7.109 +        // objects be fabricated for each reflective call on Class
   7.110 +        // objects.)
   7.111 +        Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
   7.112 +        res.root = this;
   7.113 +        return res;
   7.114 +    }
   7.115 +
   7.116 +    /**
   7.117 +     * Returns the {@code Class} object representing the class or interface
   7.118 +     * that declares the field represented by this {@code Field} object.
   7.119 +     */
   7.120 +    public Class<?> getDeclaringClass() {
   7.121 +        return clazz;
   7.122 +    }
   7.123 +
   7.124 +    /**
   7.125 +     * Returns the name of the field represented by this {@code Field} object.
   7.126 +     */
   7.127 +    public String getName() {
   7.128 +        return name;
   7.129 +    }
   7.130 +
   7.131 +    /**
   7.132 +     * Returns the Java language modifiers for the field represented
   7.133 +     * by this {@code Field} object, as an integer. The {@code Modifier} class should
   7.134 +     * be used to decode the modifiers.
   7.135 +     *
   7.136 +     * @see Modifier
   7.137 +     */
   7.138 +    public int getModifiers() {
   7.139 +        return modifiers;
   7.140 +    }
   7.141 +
   7.142 +    /**
   7.143 +     * Returns {@code true} if this field represents an element of
   7.144 +     * an enumerated type; returns {@code false} otherwise.
   7.145 +     *
   7.146 +     * @return {@code true} if and only if this field represents an element of
   7.147 +     * an enumerated type.
   7.148 +     * @since 1.5
   7.149 +     */
   7.150 +    public boolean isEnumConstant() {
   7.151 +        return (getModifiers() & Modifier.ENUM) != 0;
   7.152 +    }
   7.153 +
   7.154 +    /**
   7.155 +     * Returns {@code true} if this field is a synthetic
   7.156 +     * field; returns {@code false} otherwise.
   7.157 +     *
   7.158 +     * @return true if and only if this field is a synthetic
   7.159 +     * field as defined by the Java Language Specification.
   7.160 +     * @since 1.5
   7.161 +     */
   7.162 +    public boolean isSynthetic() {
   7.163 +        return Modifier.isSynthetic(getModifiers());
   7.164 +    }
   7.165 +
   7.166 +    /**
   7.167 +     * Returns a {@code Class} object that identifies the
   7.168 +     * declared type for the field represented by this
   7.169 +     * {@code Field} object.
   7.170 +     *
   7.171 +     * @return a {@code Class} object identifying the declared
   7.172 +     * type of the field represented by this object
   7.173 +     */
   7.174 +    public Class<?> getType() {
   7.175 +        return type;
   7.176 +    }
   7.177 +
   7.178 +    /**
   7.179 +     * Returns a {@code Type} object that represents the declared type for
   7.180 +     * the field represented by this {@code Field} object.
   7.181 +     *
   7.182 +     * <p>If the {@code Type} is a parameterized type, the
   7.183 +     * {@code Type} object returned must accurately reflect the
   7.184 +     * actual type parameters used in the source code.
   7.185 +     *
   7.186 +     * <p>If the type of the underlying field is a type variable or a
   7.187 +     * parameterized type, it is created. Otherwise, it is resolved.
   7.188 +     *
   7.189 +     * @return a {@code Type} object that represents the declared type for
   7.190 +     *     the field represented by this {@code Field} object
   7.191 +     * @throws GenericSignatureFormatError if the generic field
   7.192 +     *     signature does not conform to the format specified in
   7.193 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
   7.194 +     * @throws TypeNotPresentException if the generic type
   7.195 +     *     signature of the underlying field refers to a non-existent
   7.196 +     *     type declaration
   7.197 +     * @throws MalformedParameterizedTypeException if the generic
   7.198 +     *     signature of the underlying field refers to a parameterized type
   7.199 +     *     that cannot be instantiated for any reason
   7.200 +     * @since 1.5
   7.201 +     */
   7.202 +    public Type getGenericType() {
   7.203 +        throw new UnsupportedOperationException();
   7.204 +    }
   7.205 +
   7.206 +
   7.207 +    /**
   7.208 +     * Compares this {@code Field} against the specified object.  Returns
   7.209 +     * true if the objects are the same.  Two {@code Field} objects are the same if
   7.210 +     * they were declared by the same class and have the same name
   7.211 +     * and type.
   7.212 +     */
   7.213 +    public boolean equals(Object obj) {
   7.214 +        if (obj != null && obj instanceof Field) {
   7.215 +            Field other = (Field)obj;
   7.216 +            return (getDeclaringClass() == other.getDeclaringClass())
   7.217 +                && (getName() == other.getName())
   7.218 +                && (getType() == other.getType());
   7.219 +        }
   7.220 +        return false;
   7.221 +    }
   7.222 +
   7.223 +    /**
   7.224 +     * Returns a hashcode for this {@code Field}.  This is computed as the
   7.225 +     * exclusive-or of the hashcodes for the underlying field's
   7.226 +     * declaring class name and its name.
   7.227 +     */
   7.228 +    public int hashCode() {
   7.229 +        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
   7.230 +    }
   7.231 +
   7.232 +    /**
   7.233 +     * Returns a string describing this {@code Field}.  The format is
   7.234 +     * the access modifiers for the field, if any, followed
   7.235 +     * by the field type, followed by a space, followed by
   7.236 +     * the fully-qualified name of the class declaring the field,
   7.237 +     * followed by a period, followed by the name of the field.
   7.238 +     * For example:
   7.239 +     * <pre>
   7.240 +     *    public static final int java.lang.Thread.MIN_PRIORITY
   7.241 +     *    private int java.io.FileDescriptor.fd
   7.242 +     * </pre>
   7.243 +     *
   7.244 +     * <p>The modifiers are placed in canonical order as specified by
   7.245 +     * "The Java Language Specification".  This is {@code public},
   7.246 +     * {@code protected} or {@code private} first, and then other
   7.247 +     * modifiers in the following order: {@code static}, {@code final},
   7.248 +     * {@code transient}, {@code volatile}.
   7.249 +     */
   7.250 +    public String toString() {
   7.251 +        int mod = getModifiers();
   7.252 +        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
   7.253 +            + getTypeName(getType()) + " "
   7.254 +            + getTypeName(getDeclaringClass()) + "."
   7.255 +            + getName());
   7.256 +    }
   7.257 +
   7.258 +    /**
   7.259 +     * Returns a string describing this {@code Field}, including
   7.260 +     * its generic type.  The format is the access modifiers for the
   7.261 +     * field, if any, followed by the generic field type, followed by
   7.262 +     * a space, followed by the fully-qualified name of the class
   7.263 +     * declaring the field, followed by a period, followed by the name
   7.264 +     * of the field.
   7.265 +     *
   7.266 +     * <p>The modifiers are placed in canonical order as specified by
   7.267 +     * "The Java Language Specification".  This is {@code public},
   7.268 +     * {@code protected} or {@code private} first, and then other
   7.269 +     * modifiers in the following order: {@code static}, {@code final},
   7.270 +     * {@code transient}, {@code volatile}.
   7.271 +     *
   7.272 +     * @return a string describing this {@code Field}, including
   7.273 +     * its generic type
   7.274 +     *
   7.275 +     * @since 1.5
   7.276 +     */
   7.277 +    public String toGenericString() {
   7.278 +        int mod = getModifiers();
   7.279 +        Type fieldType = getGenericType();
   7.280 +        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
   7.281 +            +  ((fieldType instanceof Class) ?
   7.282 +                getTypeName((Class)fieldType): fieldType.toString())+ " "
   7.283 +            + getTypeName(getDeclaringClass()) + "."
   7.284 +            + getName());
   7.285 +    }
   7.286 +
   7.287 +    /**
   7.288 +     * Returns the value of the field represented by this {@code Field}, on
   7.289 +     * the specified object. The value is automatically wrapped in an
   7.290 +     * object if it has a primitive type.
   7.291 +     *
   7.292 +     * <p>The underlying field's value is obtained as follows:
   7.293 +     *
   7.294 +     * <p>If the underlying field is a static field, the {@code obj} argument
   7.295 +     * is ignored; it may be null.
   7.296 +     *
   7.297 +     * <p>Otherwise, the underlying field is an instance field.  If the
   7.298 +     * specified {@code obj} argument is null, the method throws a
   7.299 +     * {@code NullPointerException}. If the specified object is not an
   7.300 +     * instance of the class or interface declaring the underlying
   7.301 +     * field, the method throws an {@code IllegalArgumentException}.
   7.302 +     *
   7.303 +     * <p>If this {@code Field} object is enforcing Java language access control, and
   7.304 +     * the underlying field is inaccessible, the method throws an
   7.305 +     * {@code IllegalAccessException}.
   7.306 +     * If the underlying field is static, the class that declared the
   7.307 +     * field is initialized if it has not already been initialized.
   7.308 +     *
   7.309 +     * <p>Otherwise, the value is retrieved from the underlying instance
   7.310 +     * or static field.  If the field has a primitive type, the value
   7.311 +     * is wrapped in an object before being returned, otherwise it is
   7.312 +     * returned as is.
   7.313 +     *
   7.314 +     * <p>If the field is hidden in the type of {@code obj},
   7.315 +     * the field's value is obtained according to the preceding rules.
   7.316 +     *
   7.317 +     * @param obj object from which the represented field's value is
   7.318 +     * to be extracted
   7.319 +     * @return the value of the represented field in object
   7.320 +     * {@code obj}; primitive values are wrapped in an appropriate
   7.321 +     * object before being returned
   7.322 +     *
   7.323 +     * @exception IllegalAccessException    if this {@code Field} object
   7.324 +     *              is enforcing Java language access control and the underlying
   7.325 +     *              field is inaccessible.
   7.326 +     * @exception IllegalArgumentException  if the specified object is not an
   7.327 +     *              instance of the class or interface declaring the underlying
   7.328 +     *              field (or a subclass or implementor thereof).
   7.329 +     * @exception NullPointerException      if the specified object is null
   7.330 +     *              and the field is an instance field.
   7.331 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.332 +     *              by this method fails.
   7.333 +     */
   7.334 +    public Object get(Object obj)
   7.335 +        throws IllegalArgumentException, IllegalAccessException
   7.336 +    {
   7.337 +        return getFieldAccessor(obj).get(obj);
   7.338 +    }
   7.339 +
   7.340 +    /**
   7.341 +     * Gets the value of a static or instance {@code boolean} field.
   7.342 +     *
   7.343 +     * @param obj the object to extract the {@code boolean} value
   7.344 +     * from
   7.345 +     * @return the value of the {@code boolean} field
   7.346 +     *
   7.347 +     * @exception IllegalAccessException    if this {@code Field} object
   7.348 +     *              is enforcing Java language access control and the underlying
   7.349 +     *              field is inaccessible.
   7.350 +     * @exception IllegalArgumentException  if the specified object is not
   7.351 +     *              an instance of the class or interface declaring the
   7.352 +     *              underlying field (or a subclass or implementor
   7.353 +     *              thereof), or if the field value cannot be
   7.354 +     *              converted to the type {@code boolean} by a
   7.355 +     *              widening conversion.
   7.356 +     * @exception NullPointerException      if the specified object is null
   7.357 +     *              and the field is an instance field.
   7.358 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.359 +     *              by this method fails.
   7.360 +     * @see       Field#get
   7.361 +     */
   7.362 +    public boolean getBoolean(Object obj)
   7.363 +        throws IllegalArgumentException, IllegalAccessException
   7.364 +    {
   7.365 +        return getFieldAccessor(obj).getBoolean(obj);
   7.366 +    }
   7.367 +
   7.368 +    /**
   7.369 +     * Gets the value of a static or instance {@code byte} field.
   7.370 +     *
   7.371 +     * @param obj the object to extract the {@code byte} value
   7.372 +     * from
   7.373 +     * @return the value of the {@code byte} field
   7.374 +     *
   7.375 +     * @exception IllegalAccessException    if this {@code Field} object
   7.376 +     *              is enforcing Java language access control and the underlying
   7.377 +     *              field is inaccessible.
   7.378 +     * @exception IllegalArgumentException  if the specified object is not
   7.379 +     *              an instance of the class or interface declaring the
   7.380 +     *              underlying field (or a subclass or implementor
   7.381 +     *              thereof), or if the field value cannot be
   7.382 +     *              converted to the type {@code byte} by a
   7.383 +     *              widening conversion.
   7.384 +     * @exception NullPointerException      if the specified object is null
   7.385 +     *              and the field is an instance field.
   7.386 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.387 +     *              by this method fails.
   7.388 +     * @see       Field#get
   7.389 +     */
   7.390 +    public byte getByte(Object obj)
   7.391 +        throws IllegalArgumentException, IllegalAccessException
   7.392 +    {
   7.393 +        return getFieldAccessor(obj).getByte(obj);
   7.394 +    }
   7.395 +
   7.396 +    /**
   7.397 +     * Gets the value of a static or instance field of type
   7.398 +     * {@code char} or of another primitive type convertible to
   7.399 +     * type {@code char} via a widening conversion.
   7.400 +     *
   7.401 +     * @param obj the object to extract the {@code char} value
   7.402 +     * from
   7.403 +     * @return the value of the field converted to type {@code char}
   7.404 +     *
   7.405 +     * @exception IllegalAccessException    if this {@code Field} object
   7.406 +     *              is enforcing Java language access control and the underlying
   7.407 +     *              field is inaccessible.
   7.408 +     * @exception IllegalArgumentException  if the specified object is not
   7.409 +     *              an instance of the class or interface declaring the
   7.410 +     *              underlying field (or a subclass or implementor
   7.411 +     *              thereof), or if the field value cannot be
   7.412 +     *              converted to the type {@code char} by a
   7.413 +     *              widening conversion.
   7.414 +     * @exception NullPointerException      if the specified object is null
   7.415 +     *              and the field is an instance field.
   7.416 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.417 +     *              by this method fails.
   7.418 +     * @see Field#get
   7.419 +     */
   7.420 +    public char getChar(Object obj)
   7.421 +        throws IllegalArgumentException, IllegalAccessException
   7.422 +    {
   7.423 +        return getFieldAccessor(obj).getChar(obj);
   7.424 +    }
   7.425 +
   7.426 +    /**
   7.427 +     * Gets the value of a static or instance field of type
   7.428 +     * {@code short} or of another primitive type convertible to
   7.429 +     * type {@code short} via a widening conversion.
   7.430 +     *
   7.431 +     * @param obj the object to extract the {@code short} value
   7.432 +     * from
   7.433 +     * @return the value of the field converted to type {@code short}
   7.434 +     *
   7.435 +     * @exception IllegalAccessException    if this {@code Field} object
   7.436 +     *              is enforcing Java language access control and the underlying
   7.437 +     *              field is inaccessible.
   7.438 +     * @exception IllegalArgumentException  if the specified object is not
   7.439 +     *              an instance of the class or interface declaring the
   7.440 +     *              underlying field (or a subclass or implementor
   7.441 +     *              thereof), or if the field value cannot be
   7.442 +     *              converted to the type {@code short} by a
   7.443 +     *              widening conversion.
   7.444 +     * @exception NullPointerException      if the specified object is null
   7.445 +     *              and the field is an instance field.
   7.446 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.447 +     *              by this method fails.
   7.448 +     * @see       Field#get
   7.449 +     */
   7.450 +    public short getShort(Object obj)
   7.451 +        throws IllegalArgumentException, IllegalAccessException
   7.452 +    {
   7.453 +        return getFieldAccessor(obj).getShort(obj);
   7.454 +    }
   7.455 +
   7.456 +    /**
   7.457 +     * Gets the value of a static or instance field of type
   7.458 +     * {@code int} or of another primitive type convertible to
   7.459 +     * type {@code int} via a widening conversion.
   7.460 +     *
   7.461 +     * @param obj the object to extract the {@code int} value
   7.462 +     * from
   7.463 +     * @return the value of the field converted to type {@code int}
   7.464 +     *
   7.465 +     * @exception IllegalAccessException    if this {@code Field} object
   7.466 +     *              is enforcing Java language access control and the underlying
   7.467 +     *              field is inaccessible.
   7.468 +     * @exception IllegalArgumentException  if the specified object is not
   7.469 +     *              an instance of the class or interface declaring the
   7.470 +     *              underlying field (or a subclass or implementor
   7.471 +     *              thereof), or if the field value cannot be
   7.472 +     *              converted to the type {@code int} by a
   7.473 +     *              widening conversion.
   7.474 +     * @exception NullPointerException      if the specified object is null
   7.475 +     *              and the field is an instance field.
   7.476 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.477 +     *              by this method fails.
   7.478 +     * @see       Field#get
   7.479 +     */
   7.480 +    public int getInt(Object obj)
   7.481 +        throws IllegalArgumentException, IllegalAccessException
   7.482 +    {
   7.483 +        return getFieldAccessor(obj).getInt(obj);
   7.484 +    }
   7.485 +
   7.486 +    /**
   7.487 +     * Gets the value of a static or instance field of type
   7.488 +     * {@code long} or of another primitive type convertible to
   7.489 +     * type {@code long} via a widening conversion.
   7.490 +     *
   7.491 +     * @param obj the object to extract the {@code long} value
   7.492 +     * from
   7.493 +     * @return the value of the field converted to type {@code long}
   7.494 +     *
   7.495 +     * @exception IllegalAccessException    if this {@code Field} object
   7.496 +     *              is enforcing Java language access control and the underlying
   7.497 +     *              field is inaccessible.
   7.498 +     * @exception IllegalArgumentException  if the specified object is not
   7.499 +     *              an instance of the class or interface declaring the
   7.500 +     *              underlying field (or a subclass or implementor
   7.501 +     *              thereof), or if the field value cannot be
   7.502 +     *              converted to the type {@code long} by a
   7.503 +     *              widening conversion.
   7.504 +     * @exception NullPointerException      if the specified object is null
   7.505 +     *              and the field is an instance field.
   7.506 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.507 +     *              by this method fails.
   7.508 +     * @see       Field#get
   7.509 +     */
   7.510 +    public long getLong(Object obj)
   7.511 +        throws IllegalArgumentException, IllegalAccessException
   7.512 +    {
   7.513 +        return getFieldAccessor(obj).getLong(obj);
   7.514 +    }
   7.515 +
   7.516 +    /**
   7.517 +     * Gets the value of a static or instance field of type
   7.518 +     * {@code float} or of another primitive type convertible to
   7.519 +     * type {@code float} via a widening conversion.
   7.520 +     *
   7.521 +     * @param obj the object to extract the {@code float} value
   7.522 +     * from
   7.523 +     * @return the value of the field converted to type {@code float}
   7.524 +     *
   7.525 +     * @exception IllegalAccessException    if this {@code Field} object
   7.526 +     *              is enforcing Java language access control and the underlying
   7.527 +     *              field is inaccessible.
   7.528 +     * @exception IllegalArgumentException  if the specified object is not
   7.529 +     *              an instance of the class or interface declaring the
   7.530 +     *              underlying field (or a subclass or implementor
   7.531 +     *              thereof), or if the field value cannot be
   7.532 +     *              converted to the type {@code float} by a
   7.533 +     *              widening conversion.
   7.534 +     * @exception NullPointerException      if the specified object is null
   7.535 +     *              and the field is an instance field.
   7.536 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.537 +     *              by this method fails.
   7.538 +     * @see Field#get
   7.539 +     */
   7.540 +    public float getFloat(Object obj)
   7.541 +        throws IllegalArgumentException, IllegalAccessException
   7.542 +    {
   7.543 +        return getFieldAccessor(obj).getFloat(obj);
   7.544 +    }
   7.545 +
   7.546 +    /**
   7.547 +     * Gets the value of a static or instance field of type
   7.548 +     * {@code double} or of another primitive type convertible to
   7.549 +     * type {@code double} via a widening conversion.
   7.550 +     *
   7.551 +     * @param obj the object to extract the {@code double} value
   7.552 +     * from
   7.553 +     * @return the value of the field converted to type {@code double}
   7.554 +     *
   7.555 +     * @exception IllegalAccessException    if this {@code Field} object
   7.556 +     *              is enforcing Java language access control and the underlying
   7.557 +     *              field is inaccessible.
   7.558 +     * @exception IllegalArgumentException  if the specified object is not
   7.559 +     *              an instance of the class or interface declaring the
   7.560 +     *              underlying field (or a subclass or implementor
   7.561 +     *              thereof), or if the field value cannot be
   7.562 +     *              converted to the type {@code double} by a
   7.563 +     *              widening conversion.
   7.564 +     * @exception NullPointerException      if the specified object is null
   7.565 +     *              and the field is an instance field.
   7.566 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.567 +     *              by this method fails.
   7.568 +     * @see       Field#get
   7.569 +     */
   7.570 +    public double getDouble(Object obj)
   7.571 +        throws IllegalArgumentException, IllegalAccessException
   7.572 +    {
   7.573 +        return getFieldAccessor(obj).getDouble(obj);
   7.574 +    }
   7.575 +
   7.576 +    /**
   7.577 +     * Sets the field represented by this {@code Field} object on the
   7.578 +     * specified object argument to the specified new value. The new
   7.579 +     * value is automatically unwrapped if the underlying field has a
   7.580 +     * primitive type.
   7.581 +     *
   7.582 +     * <p>The operation proceeds as follows:
   7.583 +     *
   7.584 +     * <p>If the underlying field is static, the {@code obj} argument is
   7.585 +     * ignored; it may be null.
   7.586 +     *
   7.587 +     * <p>Otherwise the underlying field is an instance field.  If the
   7.588 +     * specified object argument is null, the method throws a
   7.589 +     * {@code NullPointerException}.  If the specified object argument is not
   7.590 +     * an instance of the class or interface declaring the underlying
   7.591 +     * field, the method throws an {@code IllegalArgumentException}.
   7.592 +     *
   7.593 +     * <p>If this {@code Field} object is enforcing Java language access control, and
   7.594 +     * the underlying field is inaccessible, the method throws an
   7.595 +     * {@code IllegalAccessException}.
   7.596 +     *
   7.597 +     * <p>If the underlying field is final, the method throws an
   7.598 +     * {@code IllegalAccessException} unless {@code setAccessible(true)}
   7.599 +     * has succeeded for this {@code Field} object
   7.600 +     * and the field is non-static. Setting a final field in this way
   7.601 +     * is meaningful only during deserialization or reconstruction of
   7.602 +     * instances of classes with blank final fields, before they are
   7.603 +     * made available for access by other parts of a program. Use in
   7.604 +     * any other context may have unpredictable effects, including cases
   7.605 +     * in which other parts of a program continue to use the original
   7.606 +     * value of this field.
   7.607 +     *
   7.608 +     * <p>If the underlying field is of a primitive type, an unwrapping
   7.609 +     * conversion is attempted to convert the new value to a value of
   7.610 +     * a primitive type.  If this attempt fails, the method throws an
   7.611 +     * {@code IllegalArgumentException}.
   7.612 +     *
   7.613 +     * <p>If, after possible unwrapping, the new value cannot be
   7.614 +     * converted to the type of the underlying field by an identity or
   7.615 +     * widening conversion, the method throws an
   7.616 +     * {@code IllegalArgumentException}.
   7.617 +     *
   7.618 +     * <p>If the underlying field is static, the class that declared the
   7.619 +     * field is initialized if it has not already been initialized.
   7.620 +     *
   7.621 +     * <p>The field is set to the possibly unwrapped and widened new value.
   7.622 +     *
   7.623 +     * <p>If the field is hidden in the type of {@code obj},
   7.624 +     * the field's value is set according to the preceding rules.
   7.625 +     *
   7.626 +     * @param obj the object whose field should be modified
   7.627 +     * @param value the new value for the field of {@code obj}
   7.628 +     * being modified
   7.629 +     *
   7.630 +     * @exception IllegalAccessException    if this {@code Field} object
   7.631 +     *              is enforcing Java language access control and the underlying
   7.632 +     *              field is either inaccessible or final.
   7.633 +     * @exception IllegalArgumentException  if the specified object is not an
   7.634 +     *              instance of the class or interface declaring the underlying
   7.635 +     *              field (or a subclass or implementor thereof),
   7.636 +     *              or if an unwrapping conversion fails.
   7.637 +     * @exception NullPointerException      if the specified object is null
   7.638 +     *              and the field is an instance field.
   7.639 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.640 +     *              by this method fails.
   7.641 +     */
   7.642 +    public void set(Object obj, Object value)
   7.643 +        throws IllegalArgumentException, IllegalAccessException
   7.644 +    {
   7.645 +        getFieldAccessor(obj).set(obj, value);
   7.646 +    }
   7.647 +
   7.648 +    /**
   7.649 +     * Sets the value of a field as a {@code boolean} on the specified object.
   7.650 +     * This method is equivalent to
   7.651 +     * {@code set(obj, zObj)},
   7.652 +     * where {@code zObj} is a {@code Boolean} object and
   7.653 +     * {@code zObj.booleanValue() == z}.
   7.654 +     *
   7.655 +     * @param obj the object whose field should be modified
   7.656 +     * @param z   the new value for the field of {@code obj}
   7.657 +     * being modified
   7.658 +     *
   7.659 +     * @exception IllegalAccessException    if this {@code Field} object
   7.660 +     *              is enforcing Java language access control and the underlying
   7.661 +     *              field is either inaccessible or final.
   7.662 +     * @exception IllegalArgumentException  if the specified object is not an
   7.663 +     *              instance of the class or interface declaring the underlying
   7.664 +     *              field (or a subclass or implementor thereof),
   7.665 +     *              or if an unwrapping conversion fails.
   7.666 +     * @exception NullPointerException      if the specified object is null
   7.667 +     *              and the field is an instance field.
   7.668 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.669 +     *              by this method fails.
   7.670 +     * @see       Field#set
   7.671 +     */
   7.672 +    public void setBoolean(Object obj, boolean z)
   7.673 +        throws IllegalArgumentException, IllegalAccessException
   7.674 +    {
   7.675 +        getFieldAccessor(obj).setBoolean(obj, z);
   7.676 +    }
   7.677 +
   7.678 +    /**
   7.679 +     * Sets the value of a field as a {@code byte} on the specified object.
   7.680 +     * This method is equivalent to
   7.681 +     * {@code set(obj, bObj)},
   7.682 +     * where {@code bObj} is a {@code Byte} object and
   7.683 +     * {@code bObj.byteValue() == b}.
   7.684 +     *
   7.685 +     * @param obj the object whose field should be modified
   7.686 +     * @param b   the new value for the field of {@code obj}
   7.687 +     * being modified
   7.688 +     *
   7.689 +     * @exception IllegalAccessException    if this {@code Field} object
   7.690 +     *              is enforcing Java language access control and the underlying
   7.691 +     *              field is either inaccessible or final.
   7.692 +     * @exception IllegalArgumentException  if the specified object is not an
   7.693 +     *              instance of the class or interface declaring the underlying
   7.694 +     *              field (or a subclass or implementor thereof),
   7.695 +     *              or if an unwrapping conversion fails.
   7.696 +     * @exception NullPointerException      if the specified object is null
   7.697 +     *              and the field is an instance field.
   7.698 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.699 +     *              by this method fails.
   7.700 +     * @see       Field#set
   7.701 +     */
   7.702 +    public void setByte(Object obj, byte b)
   7.703 +        throws IllegalArgumentException, IllegalAccessException
   7.704 +    {
   7.705 +        getFieldAccessor(obj).setByte(obj, b);
   7.706 +    }
   7.707 +
   7.708 +    /**
   7.709 +     * Sets the value of a field as a {@code char} on the specified object.
   7.710 +     * This method is equivalent to
   7.711 +     * {@code set(obj, cObj)},
   7.712 +     * where {@code cObj} is a {@code Character} object and
   7.713 +     * {@code cObj.charValue() == c}.
   7.714 +     *
   7.715 +     * @param obj the object whose field should be modified
   7.716 +     * @param c   the new value for the field of {@code obj}
   7.717 +     * being modified
   7.718 +     *
   7.719 +     * @exception IllegalAccessException    if this {@code Field} object
   7.720 +     *              is enforcing Java language access control and the underlying
   7.721 +     *              field is either inaccessible or final.
   7.722 +     * @exception IllegalArgumentException  if the specified object is not an
   7.723 +     *              instance of the class or interface declaring the underlying
   7.724 +     *              field (or a subclass or implementor thereof),
   7.725 +     *              or if an unwrapping conversion fails.
   7.726 +     * @exception NullPointerException      if the specified object is null
   7.727 +     *              and the field is an instance field.
   7.728 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.729 +     *              by this method fails.
   7.730 +     * @see       Field#set
   7.731 +     */
   7.732 +    public void setChar(Object obj, char c)
   7.733 +        throws IllegalArgumentException, IllegalAccessException
   7.734 +    {
   7.735 +        getFieldAccessor(obj).setChar(obj, c);
   7.736 +    }
   7.737 +
   7.738 +    /**
   7.739 +     * Sets the value of a field as a {@code short} on the specified object.
   7.740 +     * This method is equivalent to
   7.741 +     * {@code set(obj, sObj)},
   7.742 +     * where {@code sObj} is a {@code Short} object and
   7.743 +     * {@code sObj.shortValue() == s}.
   7.744 +     *
   7.745 +     * @param obj the object whose field should be modified
   7.746 +     * @param s   the new value for the field of {@code obj}
   7.747 +     * being modified
   7.748 +     *
   7.749 +     * @exception IllegalAccessException    if this {@code Field} object
   7.750 +     *              is enforcing Java language access control and the underlying
   7.751 +     *              field is either inaccessible or final.
   7.752 +     * @exception IllegalArgumentException  if the specified object is not an
   7.753 +     *              instance of the class or interface declaring the underlying
   7.754 +     *              field (or a subclass or implementor thereof),
   7.755 +     *              or if an unwrapping conversion fails.
   7.756 +     * @exception NullPointerException      if the specified object is null
   7.757 +     *              and the field is an instance field.
   7.758 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.759 +     *              by this method fails.
   7.760 +     * @see       Field#set
   7.761 +     */
   7.762 +    public void setShort(Object obj, short s)
   7.763 +        throws IllegalArgumentException, IllegalAccessException
   7.764 +    {
   7.765 +        getFieldAccessor(obj).setShort(obj, s);
   7.766 +    }
   7.767 +
   7.768 +    /**
   7.769 +     * Sets the value of a field as an {@code int} on the specified object.
   7.770 +     * This method is equivalent to
   7.771 +     * {@code set(obj, iObj)},
   7.772 +     * where {@code iObj} is a {@code Integer} object and
   7.773 +     * {@code iObj.intValue() == i}.
   7.774 +     *
   7.775 +     * @param obj the object whose field should be modified
   7.776 +     * @param i   the new value for the field of {@code obj}
   7.777 +     * being modified
   7.778 +     *
   7.779 +     * @exception IllegalAccessException    if this {@code Field} object
   7.780 +     *              is enforcing Java language access control and the underlying
   7.781 +     *              field is either inaccessible or final.
   7.782 +     * @exception IllegalArgumentException  if the specified object is not an
   7.783 +     *              instance of the class or interface declaring the underlying
   7.784 +     *              field (or a subclass or implementor thereof),
   7.785 +     *              or if an unwrapping conversion fails.
   7.786 +     * @exception NullPointerException      if the specified object is null
   7.787 +     *              and the field is an instance field.
   7.788 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.789 +     *              by this method fails.
   7.790 +     * @see       Field#set
   7.791 +     */
   7.792 +    public void setInt(Object obj, int i)
   7.793 +        throws IllegalArgumentException, IllegalAccessException
   7.794 +    {
   7.795 +        getFieldAccessor(obj).setInt(obj, i);
   7.796 +    }
   7.797 +
   7.798 +    /**
   7.799 +     * Sets the value of a field as a {@code long} on the specified object.
   7.800 +     * This method is equivalent to
   7.801 +     * {@code set(obj, lObj)},
   7.802 +     * where {@code lObj} is a {@code Long} object and
   7.803 +     * {@code lObj.longValue() == l}.
   7.804 +     *
   7.805 +     * @param obj the object whose field should be modified
   7.806 +     * @param l   the new value for the field of {@code obj}
   7.807 +     * being modified
   7.808 +     *
   7.809 +     * @exception IllegalAccessException    if this {@code Field} object
   7.810 +     *              is enforcing Java language access control and the underlying
   7.811 +     *              field is either inaccessible or final.
   7.812 +     * @exception IllegalArgumentException  if the specified object is not an
   7.813 +     *              instance of the class or interface declaring the underlying
   7.814 +     *              field (or a subclass or implementor thereof),
   7.815 +     *              or if an unwrapping conversion fails.
   7.816 +     * @exception NullPointerException      if the specified object is null
   7.817 +     *              and the field is an instance field.
   7.818 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.819 +     *              by this method fails.
   7.820 +     * @see       Field#set
   7.821 +     */
   7.822 +    public void setLong(Object obj, long l)
   7.823 +        throws IllegalArgumentException, IllegalAccessException
   7.824 +    {
   7.825 +        getFieldAccessor(obj).setLong(obj, l);
   7.826 +    }
   7.827 +
   7.828 +    /**
   7.829 +     * Sets the value of a field as a {@code float} on the specified object.
   7.830 +     * This method is equivalent to
   7.831 +     * {@code set(obj, fObj)},
   7.832 +     * where {@code fObj} is a {@code Float} object and
   7.833 +     * {@code fObj.floatValue() == f}.
   7.834 +     *
   7.835 +     * @param obj the object whose field should be modified
   7.836 +     * @param f   the new value for the field of {@code obj}
   7.837 +     * being modified
   7.838 +     *
   7.839 +     * @exception IllegalAccessException    if this {@code Field} object
   7.840 +     *              is enforcing Java language access control and the underlying
   7.841 +     *              field is either inaccessible or final.
   7.842 +     * @exception IllegalArgumentException  if the specified object is not an
   7.843 +     *              instance of the class or interface declaring the underlying
   7.844 +     *              field (or a subclass or implementor thereof),
   7.845 +     *              or if an unwrapping conversion fails.
   7.846 +     * @exception NullPointerException      if the specified object is null
   7.847 +     *              and the field is an instance field.
   7.848 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.849 +     *              by this method fails.
   7.850 +     * @see       Field#set
   7.851 +     */
   7.852 +    public void setFloat(Object obj, float f)
   7.853 +        throws IllegalArgumentException, IllegalAccessException
   7.854 +    {
   7.855 +        getFieldAccessor(obj).setFloat(obj, f);
   7.856 +    }
   7.857 +
   7.858 +    /**
   7.859 +     * Sets the value of a field as a {@code double} on the specified object.
   7.860 +     * This method is equivalent to
   7.861 +     * {@code set(obj, dObj)},
   7.862 +     * where {@code dObj} is a {@code Double} object and
   7.863 +     * {@code dObj.doubleValue() == d}.
   7.864 +     *
   7.865 +     * @param obj the object whose field should be modified
   7.866 +     * @param d   the new value for the field of {@code obj}
   7.867 +     * being modified
   7.868 +     *
   7.869 +     * @exception IllegalAccessException    if this {@code Field} object
   7.870 +     *              is enforcing Java language access control and the underlying
   7.871 +     *              field is either inaccessible or final.
   7.872 +     * @exception IllegalArgumentException  if the specified object is not an
   7.873 +     *              instance of the class or interface declaring the underlying
   7.874 +     *              field (or a subclass or implementor thereof),
   7.875 +     *              or if an unwrapping conversion fails.
   7.876 +     * @exception NullPointerException      if the specified object is null
   7.877 +     *              and the field is an instance field.
   7.878 +     * @exception ExceptionInInitializerError if the initialization provoked
   7.879 +     *              by this method fails.
   7.880 +     * @see       Field#set
   7.881 +     */
   7.882 +    public void setDouble(Object obj, double d)
   7.883 +        throws IllegalArgumentException, IllegalAccessException
   7.884 +    {
   7.885 +        getFieldAccessor(obj).setDouble(obj, d);
   7.886 +    }
   7.887 +
   7.888 +    // Convenience routine which performs security checks
   7.889 +    private FieldAccessor getFieldAccessor(Object obj)
   7.890 +        throws IllegalAccessException
   7.891 +    {
   7.892 +        throw new SecurityException();
   7.893 +    }
   7.894 +    
   7.895 +    private static abstract class FieldAccessor {
   7.896 +        abstract void setShort(Object obj, short s);
   7.897 +        abstract void setInt(Object obj, int i);
   7.898 +        abstract void setChar(Object obj, char c);
   7.899 +        abstract void setByte(Object obj, byte b);
   7.900 +        abstract void setBoolean(Object obj, boolean z);
   7.901 +        abstract void set(Object obj, Object value);
   7.902 +        abstract double getDouble(Object obj);
   7.903 +        abstract void setLong(Object obj, long l);
   7.904 +        abstract void setFloat(Object obj, float f);
   7.905 +        abstract void setDouble(Object obj, double d);
   7.906 +        abstract long getLong(Object obj);
   7.907 +        abstract int getInt(Object obj);
   7.908 +        abstract short getShort(Object obj);
   7.909 +        abstract char getChar(Object obj);
   7.910 +        abstract byte getByte(Object obj);
   7.911 +        abstract boolean getBoolean(Object obj);
   7.912 +        abstract Object get(Object obj);
   7.913 +        abstract float getFloat(Object obj);
   7.914 +    }
   7.915 +
   7.916 +    /*
   7.917 +     * Utility routine to paper over array type names
   7.918 +     */
   7.919 +    static String getTypeName(Class<?> type) {
   7.920 +        if (type.isArray()) {
   7.921 +            try {
   7.922 +                Class<?> cl = type;
   7.923 +                int dimensions = 0;
   7.924 +                while (cl.isArray()) {
   7.925 +                    dimensions++;
   7.926 +                    cl = cl.getComponentType();
   7.927 +                }
   7.928 +                StringBuffer sb = new StringBuffer();
   7.929 +                sb.append(cl.getName());
   7.930 +                for (int i = 0; i < dimensions; i++) {
   7.931 +                    sb.append("[]");
   7.932 +                }
   7.933 +                return sb.toString();
   7.934 +            } catch (Throwable e) { /*FALLTHRU*/ }
   7.935 +        }
   7.936 +        return type.getName();
   7.937 +    }
   7.938 +
   7.939 +    /**
   7.940 +     * @throws NullPointerException {@inheritDoc}
   7.941 +     * @since 1.5
   7.942 +     */
   7.943 +    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   7.944 +        if (annotationClass == null)
   7.945 +            throw new NullPointerException();
   7.946 +
   7.947 +        throw new UnsupportedOperationException();
   7.948 +    }
   7.949 +
   7.950 +    /**
   7.951 +     * @since 1.5
   7.952 +     */
   7.953 +    public Annotation[] getDeclaredAnnotations()  {
   7.954 +        throw new UnsupportedOperationException();
   7.955 +    }
   7.956 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/emul/src/main/java/java/lang/reflect/GenericDeclaration.java	Wed Dec 12 12:41:06 2012 +0100
     8.3 @@ -0,0 +1,49 @@
     8.4 +/*
     8.5 + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +
    8.29 +package java.lang.reflect;
    8.30 +
    8.31 +/**
    8.32 + * A common interface for all entities that declare type variables.
    8.33 + *
    8.34 + * @since 1.5
    8.35 + */
    8.36 +public interface GenericDeclaration {
    8.37 +    /**
    8.38 +     * Returns an array of {@code TypeVariable} objects that
    8.39 +     * represent the type variables declared by the generic
    8.40 +     * declaration represented by this {@code GenericDeclaration}
    8.41 +     * object, in declaration order.  Returns an array of length 0 if
    8.42 +     * the underlying generic declaration declares no type variables.
    8.43 +     *
    8.44 +     * @return an array of {@code TypeVariable} objects that represent
    8.45 +     *     the type variables declared by this generic declaration
    8.46 +     * @throws GenericSignatureFormatError if the generic
    8.47 +     *     signature of this generic declaration does not conform to
    8.48 +     *     the format specified in
    8.49 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
    8.50 +     */
    8.51 +    public TypeVariable<?>[] getTypeParameters();
    8.52 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/emul/src/main/java/java/lang/reflect/InvocationTargetException.java	Wed Dec 12 12:41:06 2012 +0100
     9.3 @@ -0,0 +1,111 @@
     9.4 +/*
     9.5 + * Copyright (c) 1996, 2004, 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 +/**
    9.32 + * InvocationTargetException is a checked exception that wraps
    9.33 + * an exception thrown by an invoked method or constructor.
    9.34 + *
    9.35 + * <p>As of release 1.4, this exception has been retrofitted to conform to
    9.36 + * the general purpose exception-chaining mechanism.  The "target exception"
    9.37 + * that is provided at construction time and accessed via the
    9.38 + * {@link #getTargetException()} method is now known as the <i>cause</i>,
    9.39 + * and may be accessed via the {@link Throwable#getCause()} method,
    9.40 + * as well as the aforementioned "legacy method."
    9.41 + *
    9.42 + * @see Method
    9.43 + * @see Constructor
    9.44 + */
    9.45 +public class InvocationTargetException extends ReflectiveOperationException {
    9.46 +    /**
    9.47 +     * Use serialVersionUID from JDK 1.1.X for interoperability
    9.48 +     */
    9.49 +    private static final long serialVersionUID = 4085088731926701167L;
    9.50 +
    9.51 +     /**
    9.52 +     * This field holds the target if the
    9.53 +     * InvocationTargetException(Throwable target) constructor was
    9.54 +     * used to instantiate the object
    9.55 +     *
    9.56 +     * @serial
    9.57 +     *
    9.58 +     */
    9.59 +    private Throwable target;
    9.60 +
    9.61 +    /**
    9.62 +     * Constructs an {@code InvocationTargetException} with
    9.63 +     * {@code null} as the target exception.
    9.64 +     */
    9.65 +    protected InvocationTargetException() {
    9.66 +        super((Throwable)null);  // Disallow initCause
    9.67 +    }
    9.68 +
    9.69 +    /**
    9.70 +     * Constructs a InvocationTargetException with a target exception.
    9.71 +     *
    9.72 +     * @param target the target exception
    9.73 +     */
    9.74 +    public InvocationTargetException(Throwable target) {
    9.75 +        super((Throwable)null);  // Disallow initCause
    9.76 +        this.target = target;
    9.77 +    }
    9.78 +
    9.79 +    /**
    9.80 +     * Constructs a InvocationTargetException with a target exception
    9.81 +     * and a detail message.
    9.82 +     *
    9.83 +     * @param target the target exception
    9.84 +     * @param s      the detail message
    9.85 +     */
    9.86 +    public InvocationTargetException(Throwable target, String s) {
    9.87 +        super(s, null);  // Disallow initCause
    9.88 +        this.target = target;
    9.89 +    }
    9.90 +
    9.91 +    /**
    9.92 +     * Get the thrown target exception.
    9.93 +     *
    9.94 +     * <p>This method predates the general-purpose exception chaining facility.
    9.95 +     * The {@link Throwable#getCause()} method is now the preferred means of
    9.96 +     * obtaining this information.
    9.97 +     *
    9.98 +     * @return the thrown target exception (cause of this exception).
    9.99 +     */
   9.100 +    public Throwable getTargetException() {
   9.101 +        return target;
   9.102 +    }
   9.103 +
   9.104 +    /**
   9.105 +     * Returns the cause of this exception (the thrown target exception,
   9.106 +     * which may be {@code null}).
   9.107 +     *
   9.108 +     * @return  the cause of this exception.
   9.109 +     * @since   1.4
   9.110 +     */
   9.111 +    public Throwable getCause() {
   9.112 +        return target;
   9.113 +    }
   9.114 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/emul/src/main/java/java/lang/reflect/Member.java	Wed Dec 12 12:41:06 2012 +0100
    10.3 @@ -0,0 +1,93 @@
    10.4 +/*
    10.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.  Oracle designates this
   10.11 + * particular file as subject to the "Classpath" exception as provided
   10.12 + * by Oracle in the LICENSE file that accompanied this code.
   10.13 + *
   10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 + * version 2 for more details (a copy is included in the LICENSE file that
   10.18 + * accompanied this code).
   10.19 + *
   10.20 + * You should have received a copy of the GNU General Public License version
   10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 + *
   10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 + * or visit www.oracle.com if you need additional information or have any
   10.26 + * questions.
   10.27 + */
   10.28 +
   10.29 +package java.lang.reflect;
   10.30 +
   10.31 +/**
   10.32 + * Member is an interface that reflects identifying information about
   10.33 + * a single member (a field or a method) or a constructor.
   10.34 + *
   10.35 + * @see java.lang.Class
   10.36 + * @see Field
   10.37 + * @see Method
   10.38 + * @see Constructor
   10.39 + *
   10.40 + * @author Nakul Saraiya
   10.41 + */
   10.42 +public
   10.43 +interface Member {
   10.44 +
   10.45 +    /**
   10.46 +     * Identifies the set of all public members of a class or interface,
   10.47 +     * including inherited members.
   10.48 +     * @see java.lang.SecurityManager#checkMemberAccess
   10.49 +     */
   10.50 +    public static final int PUBLIC = 0;
   10.51 +
   10.52 +    /**
   10.53 +     * Identifies the set of declared members of a class or interface.
   10.54 +     * Inherited members are not included.
   10.55 +     * @see java.lang.SecurityManager#checkMemberAccess
   10.56 +     */
   10.57 +    public static final int DECLARED = 1;
   10.58 +
   10.59 +    /**
   10.60 +     * Returns the Class object representing the class or interface
   10.61 +     * that declares the member or constructor represented by this Member.
   10.62 +     *
   10.63 +     * @return an object representing the declaring class of the
   10.64 +     * underlying member
   10.65 +     */
   10.66 +    public Class<?> getDeclaringClass();
   10.67 +
   10.68 +    /**
   10.69 +     * Returns the simple name of the underlying member or constructor
   10.70 +     * represented by this Member.
   10.71 +     *
   10.72 +     * @return the simple name of the underlying member
   10.73 +     */
   10.74 +    public String getName();
   10.75 +
   10.76 +    /**
   10.77 +     * Returns the Java language modifiers for the member or
   10.78 +     * constructor represented by this Member, as an integer.  The
   10.79 +     * Modifier class should be used to decode the modifiers in
   10.80 +     * the integer.
   10.81 +     *
   10.82 +     * @return the Java language modifiers for the underlying member
   10.83 +     * @see Modifier
   10.84 +     */
   10.85 +    public int getModifiers();
   10.86 +
   10.87 +    /**
   10.88 +     * Returns {@code true} if this member was introduced by
   10.89 +     * the compiler; returns {@code false} otherwise.
   10.90 +     *
   10.91 +     * @return true if and only if this member was introduced by
   10.92 +     * the compiler.
   10.93 +     * @since 1.5
   10.94 +     */
   10.95 +    public boolean isSynthetic();
   10.96 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Wed Dec 12 12:41:06 2012 +0100
    11.3 @@ -0,0 +1,655 @@
    11.4 +/*
    11.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +package java.lang.reflect;
   11.30 +
   11.31 +import java.lang.annotation.Annotation;
   11.32 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   11.33 +import org.apidesign.bck2brwsr.emul.AnnotationImpl;
   11.34 +
   11.35 +/**
   11.36 + * A {@code Method} provides information about, and access to, a single method
   11.37 + * on a class or interface.  The reflected method may be a class method
   11.38 + * or an instance method (including an abstract method).
   11.39 + *
   11.40 + * <p>A {@code Method} permits widening conversions to occur when matching the
   11.41 + * actual parameters to invoke with the underlying method's formal
   11.42 + * parameters, but it throws an {@code IllegalArgumentException} if a
   11.43 + * narrowing conversion would occur.
   11.44 + *
   11.45 + * @see Member
   11.46 + * @see java.lang.Class
   11.47 + * @see java.lang.Class#getMethods()
   11.48 + * @see java.lang.Class#getMethod(String, Class[])
   11.49 + * @see java.lang.Class#getDeclaredMethods()
   11.50 + * @see java.lang.Class#getDeclaredMethod(String, Class[])
   11.51 + *
   11.52 + * @author Kenneth Russell
   11.53 + * @author Nakul Saraiya
   11.54 + */
   11.55 +public final
   11.56 +    class Method extends AccessibleObject implements GenericDeclaration,
   11.57 +                                                     Member {
   11.58 +    private final Class<?> clazz;
   11.59 +    private final String name;
   11.60 +    private final Object data;
   11.61 +    private final String sig;
   11.62 +    private int modifiers;
   11.63 +
   11.64 +   // Generics infrastructure
   11.65 +
   11.66 +    private String getGenericSignature() {return null;}
   11.67 +
   11.68 +    /**
   11.69 +     * Package-private constructor used by ReflectAccess to enable
   11.70 +     * instantiation of these objects in Java code from the java.lang
   11.71 +     * package via sun.reflect.LangReflectAccess.
   11.72 +     */
   11.73 +    Method(Class<?> declaringClass, String name, Object data, String sig)
   11.74 +    {
   11.75 +        this.clazz = declaringClass;
   11.76 +        this.name = name;
   11.77 +        this.data = data;
   11.78 +        this.sig = sig;
   11.79 +    }
   11.80 +
   11.81 +    /**
   11.82 +     * Package-private routine (exposed to java.lang.Class via
   11.83 +     * ReflectAccess) which returns a copy of this Method. The copy's
   11.84 +     * "root" field points to this Method.
   11.85 +     */
   11.86 +    Method copy() {
   11.87 +        return this;
   11.88 +    }
   11.89 +
   11.90 +    /**
   11.91 +     * Returns the {@code Class} object representing the class or interface
   11.92 +     * that declares the method represented by this {@code Method} object.
   11.93 +     */
   11.94 +    public Class<?> getDeclaringClass() {
   11.95 +        return clazz;
   11.96 +    }
   11.97 +
   11.98 +    /**
   11.99 +     * Returns the name of the method represented by this {@code Method}
  11.100 +     * object, as a {@code String}.
  11.101 +     */
  11.102 +    public String getName() {
  11.103 +        return name;
  11.104 +    }
  11.105 +
  11.106 +    /**
  11.107 +     * Returns the Java language modifiers for the method represented
  11.108 +     * by this {@code Method} object, as an integer. The {@code Modifier} class should
  11.109 +     * be used to decode the modifiers.
  11.110 +     *
  11.111 +     * @see Modifier
  11.112 +     */
  11.113 +    public int getModifiers() {
  11.114 +        return modifiers;
  11.115 +    }
  11.116 +
  11.117 +    /**
  11.118 +     * Returns an array of {@code TypeVariable} objects that represent the
  11.119 +     * type variables declared by the generic declaration represented by this
  11.120 +     * {@code GenericDeclaration} object, in declaration order.  Returns an
  11.121 +     * array of length 0 if the underlying generic declaration declares no type
  11.122 +     * variables.
  11.123 +     *
  11.124 +     * @return an array of {@code TypeVariable} objects that represent
  11.125 +     *     the type variables declared by this generic declaration
  11.126 +     * @throws GenericSignatureFormatError if the generic
  11.127 +     *     signature of this generic declaration does not conform to
  11.128 +     *     the format specified in
  11.129 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  11.130 +     * @since 1.5
  11.131 +     */
  11.132 +    public TypeVariable<Method>[] getTypeParameters() {
  11.133 +        throw new UnsupportedOperationException();
  11.134 +    }
  11.135 +
  11.136 +    /**
  11.137 +     * Returns a {@code Class} object that represents the formal return type
  11.138 +     * of the method represented by this {@code Method} object.
  11.139 +     *
  11.140 +     * @return the return type for the method this object represents
  11.141 +     */
  11.142 +    public Class<?> getReturnType() {
  11.143 +        throw new UnsupportedOperationException();
  11.144 +    }
  11.145 +
  11.146 +    /**
  11.147 +     * Returns a {@code Type} object that represents the formal return
  11.148 +     * type of the method represented by this {@code Method} object.
  11.149 +     *
  11.150 +     * <p>If the return type is a parameterized type,
  11.151 +     * the {@code Type} object returned must accurately reflect
  11.152 +     * the actual type parameters used in the source code.
  11.153 +     *
  11.154 +     * <p>If the return type is a type variable or a parameterized type, it
  11.155 +     * is created. Otherwise, it is resolved.
  11.156 +     *
  11.157 +     * @return  a {@code Type} object that represents the formal return
  11.158 +     *     type of the underlying  method
  11.159 +     * @throws GenericSignatureFormatError
  11.160 +     *     if the generic method signature does not conform to the format
  11.161 +     *     specified in
  11.162 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  11.163 +     * @throws TypeNotPresentException if the underlying method's
  11.164 +     *     return type refers to a non-existent type declaration
  11.165 +     * @throws MalformedParameterizedTypeException if the
  11.166 +     *     underlying method's return typed refers to a parameterized
  11.167 +     *     type that cannot be instantiated for any reason
  11.168 +     * @since 1.5
  11.169 +     */
  11.170 +    public Type getGenericReturnType() {
  11.171 +        throw new UnsupportedOperationException();
  11.172 +    }
  11.173 +
  11.174 +
  11.175 +    /**
  11.176 +     * Returns an array of {@code Class} objects that represent the formal
  11.177 +     * parameter types, in declaration order, of the method
  11.178 +     * represented by this {@code Method} object.  Returns an array of length
  11.179 +     * 0 if the underlying method takes no parameters.
  11.180 +     *
  11.181 +     * @return the parameter types for the method this object
  11.182 +     * represents
  11.183 +     */
  11.184 +    public Class<?>[] getParameterTypes() {
  11.185 +        throw new UnsupportedOperationException();
  11.186 +        //return (Class<?>[]) parameterTypes.clone();
  11.187 +    }
  11.188 +
  11.189 +    /**
  11.190 +     * Returns an array of {@code Type} objects that represent the formal
  11.191 +     * parameter types, in declaration order, of the method represented by
  11.192 +     * this {@code Method} object. Returns an array of length 0 if the
  11.193 +     * underlying method takes no parameters.
  11.194 +     *
  11.195 +     * <p>If a formal parameter type is a parameterized type,
  11.196 +     * the {@code Type} object returned for it must accurately reflect
  11.197 +     * the actual type parameters used in the source code.
  11.198 +     *
  11.199 +     * <p>If a formal parameter type is a type variable or a parameterized
  11.200 +     * type, it is created. Otherwise, it is resolved.
  11.201 +     *
  11.202 +     * @return an array of Types that represent the formal
  11.203 +     *     parameter types of the underlying method, in declaration order
  11.204 +     * @throws GenericSignatureFormatError
  11.205 +     *     if the generic method signature does not conform to the format
  11.206 +     *     specified in
  11.207 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  11.208 +     * @throws TypeNotPresentException if any of the parameter
  11.209 +     *     types of the underlying method refers to a non-existent type
  11.210 +     *     declaration
  11.211 +     * @throws MalformedParameterizedTypeException if any of
  11.212 +     *     the underlying method's parameter types refer to a parameterized
  11.213 +     *     type that cannot be instantiated for any reason
  11.214 +     * @since 1.5
  11.215 +     */
  11.216 +    public Type[] getGenericParameterTypes() {
  11.217 +        throw new UnsupportedOperationException();
  11.218 +    }
  11.219 +
  11.220 +
  11.221 +    /**
  11.222 +     * Returns an array of {@code Class} objects that represent
  11.223 +     * the types of the exceptions declared to be thrown
  11.224 +     * by the underlying method
  11.225 +     * represented by this {@code Method} object.  Returns an array of length
  11.226 +     * 0 if the method declares no exceptions in its {@code throws} clause.
  11.227 +     *
  11.228 +     * @return the exception types declared as being thrown by the
  11.229 +     * method this object represents
  11.230 +     */
  11.231 +    public Class<?>[] getExceptionTypes() {
  11.232 +        throw new UnsupportedOperationException();
  11.233 +        //return (Class<?>[]) exceptionTypes.clone();
  11.234 +    }
  11.235 +
  11.236 +    /**
  11.237 +     * Returns an array of {@code Type} objects that represent the
  11.238 +     * exceptions declared to be thrown by this {@code Method} object.
  11.239 +     * Returns an array of length 0 if the underlying method declares
  11.240 +     * no exceptions in its {@code throws} clause.
  11.241 +     *
  11.242 +     * <p>If an exception type is a type variable or a parameterized
  11.243 +     * type, it is created. Otherwise, it is resolved.
  11.244 +     *
  11.245 +     * @return an array of Types that represent the exception types
  11.246 +     *     thrown by the underlying method
  11.247 +     * @throws GenericSignatureFormatError
  11.248 +     *     if the generic method signature does not conform to the format
  11.249 +     *     specified in
  11.250 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  11.251 +     * @throws TypeNotPresentException if the underlying method's
  11.252 +     *     {@code throws} clause refers to a non-existent type declaration
  11.253 +     * @throws MalformedParameterizedTypeException if
  11.254 +     *     the underlying method's {@code throws} clause refers to a
  11.255 +     *     parameterized type that cannot be instantiated for any reason
  11.256 +     * @since 1.5
  11.257 +     */
  11.258 +      public Type[] getGenericExceptionTypes() {
  11.259 +        throw new UnsupportedOperationException();
  11.260 +      }
  11.261 +
  11.262 +    /**
  11.263 +     * Compares this {@code Method} against the specified object.  Returns
  11.264 +     * true if the objects are the same.  Two {@code Methods} are the same if
  11.265 +     * they were declared by the same class and have the same name
  11.266 +     * and formal parameter types and return type.
  11.267 +     */
  11.268 +    public boolean equals(Object obj) {
  11.269 +        if (obj != null && obj instanceof Method) {
  11.270 +            Method other = (Method)obj;
  11.271 +            return data == other.data;
  11.272 +        }
  11.273 +        return false;
  11.274 +    }
  11.275 +
  11.276 +    /**
  11.277 +     * Returns a hashcode for this {@code Method}.  The hashcode is computed
  11.278 +     * as the exclusive-or of the hashcodes for the underlying
  11.279 +     * method's declaring class name and the method's name.
  11.280 +     */
  11.281 +    public int hashCode() {
  11.282 +        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  11.283 +    }
  11.284 +
  11.285 +    /**
  11.286 +     * Returns a string describing this {@code Method}.  The string is
  11.287 +     * formatted as the method access modifiers, if any, followed by
  11.288 +     * the method return type, followed by a space, followed by the
  11.289 +     * class declaring the method, followed by a period, followed by
  11.290 +     * the method name, followed by a parenthesized, comma-separated
  11.291 +     * list of the method's formal parameter types. If the method
  11.292 +     * throws checked exceptions, the parameter list is followed by a
  11.293 +     * space, followed by the word throws followed by a
  11.294 +     * comma-separated list of the thrown exception types.
  11.295 +     * For example:
  11.296 +     * <pre>
  11.297 +     *    public boolean java.lang.Object.equals(java.lang.Object)
  11.298 +     * </pre>
  11.299 +     *
  11.300 +     * <p>The access modifiers are placed in canonical order as
  11.301 +     * specified by "The Java Language Specification".  This is
  11.302 +     * {@code public}, {@code protected} or {@code private} first,
  11.303 +     * and then other modifiers in the following order:
  11.304 +     * {@code abstract}, {@code static}, {@code final},
  11.305 +     * {@code synchronized}, {@code native}, {@code strictfp}.
  11.306 +     */
  11.307 +    public String toString() {
  11.308 +        try {
  11.309 +            StringBuilder sb = new StringBuilder();
  11.310 +            int mod = getModifiers() & Modifier.methodModifiers();
  11.311 +            if (mod != 0) {
  11.312 +                sb.append(Modifier.toString(mod)).append(' ');
  11.313 +            }
  11.314 +            sb.append(Field.getTypeName(getReturnType())).append(' ');
  11.315 +            sb.append(Field.getTypeName(getDeclaringClass())).append('.');
  11.316 +            sb.append(getName()).append('(');
  11.317 +            /*
  11.318 +            Class<?>[] params = parameterTypes; // avoid clone
  11.319 +            for (int j = 0; j < params.length; j++) {
  11.320 +                sb.append(Field.getTypeName(params[j]));
  11.321 +                if (j < (params.length - 1))
  11.322 +                    sb.append(',');
  11.323 +            }
  11.324 +            sb.append(')');
  11.325 +            Class<?>[] exceptions = exceptionTypes; // avoid clone
  11.326 +            if (exceptions.length > 0) {
  11.327 +                sb.append(" throws ");
  11.328 +                for (int k = 0; k < exceptions.length; k++) {
  11.329 +                    sb.append(exceptions[k].getName());
  11.330 +                    if (k < (exceptions.length - 1))
  11.331 +                        sb.append(',');
  11.332 +                }
  11.333 +            }
  11.334 +            */
  11.335 +            return sb.toString();
  11.336 +        } catch (Exception e) {
  11.337 +            return "<" + e + ">";
  11.338 +        }
  11.339 +    }
  11.340 +
  11.341 +    /**
  11.342 +     * Returns a string describing this {@code Method}, including
  11.343 +     * type parameters.  The string is formatted as the method access
  11.344 +     * modifiers, if any, followed by an angle-bracketed
  11.345 +     * comma-separated list of the method's type parameters, if any,
  11.346 +     * followed by the method's generic return type, followed by a
  11.347 +     * space, followed by the class declaring the method, followed by
  11.348 +     * a period, followed by the method name, followed by a
  11.349 +     * parenthesized, comma-separated list of the method's generic
  11.350 +     * formal parameter types.
  11.351 +     *
  11.352 +     * If this method was declared to take a variable number of
  11.353 +     * arguments, instead of denoting the last parameter as
  11.354 +     * "<tt><i>Type</i>[]</tt>", it is denoted as
  11.355 +     * "<tt><i>Type</i>...</tt>".
  11.356 +     *
  11.357 +     * A space is used to separate access modifiers from one another
  11.358 +     * and from the type parameters or return type.  If there are no
  11.359 +     * type parameters, the type parameter list is elided; if the type
  11.360 +     * parameter list is present, a space separates the list from the
  11.361 +     * class name.  If the method is declared to throw exceptions, the
  11.362 +     * parameter list is followed by a space, followed by the word
  11.363 +     * throws followed by a comma-separated list of the generic thrown
  11.364 +     * exception types.  If there are no type parameters, the type
  11.365 +     * parameter list is elided.
  11.366 +     *
  11.367 +     * <p>The access modifiers are placed in canonical order as
  11.368 +     * specified by "The Java Language Specification".  This is
  11.369 +     * {@code public}, {@code protected} or {@code private} first,
  11.370 +     * and then other modifiers in the following order:
  11.371 +     * {@code abstract}, {@code static}, {@code final},
  11.372 +     * {@code synchronized}, {@code native}, {@code strictfp}.
  11.373 +     *
  11.374 +     * @return a string describing this {@code Method},
  11.375 +     * include type parameters
  11.376 +     *
  11.377 +     * @since 1.5
  11.378 +     */
  11.379 +    public String toGenericString() {
  11.380 +        try {
  11.381 +            StringBuilder sb = new StringBuilder();
  11.382 +            int mod = getModifiers() & Modifier.methodModifiers();
  11.383 +            if (mod != 0) {
  11.384 +                sb.append(Modifier.toString(mod)).append(' ');
  11.385 +            }
  11.386 +            TypeVariable<?>[] typeparms = getTypeParameters();
  11.387 +            if (typeparms.length > 0) {
  11.388 +                boolean first = true;
  11.389 +                sb.append('<');
  11.390 +                for(TypeVariable<?> typeparm: typeparms) {
  11.391 +                    if (!first)
  11.392 +                        sb.append(',');
  11.393 +                    // Class objects can't occur here; no need to test
  11.394 +                    // and call Class.getName().
  11.395 +                    sb.append(typeparm.toString());
  11.396 +                    first = false;
  11.397 +                }
  11.398 +                sb.append("> ");
  11.399 +            }
  11.400 +
  11.401 +            Type genRetType = getGenericReturnType();
  11.402 +            sb.append( ((genRetType instanceof Class<?>)?
  11.403 +                        Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
  11.404 +                    .append(' ');
  11.405 +
  11.406 +            sb.append(Field.getTypeName(getDeclaringClass())).append('.');
  11.407 +            sb.append(getName()).append('(');
  11.408 +            Type[] params = getGenericParameterTypes();
  11.409 +            for (int j = 0; j < params.length; j++) {
  11.410 +                String param = (params[j] instanceof Class)?
  11.411 +                    Field.getTypeName((Class)params[j]):
  11.412 +                    (params[j].toString());
  11.413 +                if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
  11.414 +                    param = param.replaceFirst("\\[\\]$", "...");
  11.415 +                sb.append(param);
  11.416 +                if (j < (params.length - 1))
  11.417 +                    sb.append(',');
  11.418 +            }
  11.419 +            sb.append(')');
  11.420 +            Type[] exceptions = getGenericExceptionTypes();
  11.421 +            if (exceptions.length > 0) {
  11.422 +                sb.append(" throws ");
  11.423 +                for (int k = 0; k < exceptions.length; k++) {
  11.424 +                    sb.append((exceptions[k] instanceof Class)?
  11.425 +                              ((Class)exceptions[k]).getName():
  11.426 +                              exceptions[k].toString());
  11.427 +                    if (k < (exceptions.length - 1))
  11.428 +                        sb.append(',');
  11.429 +                }
  11.430 +            }
  11.431 +            return sb.toString();
  11.432 +        } catch (Exception e) {
  11.433 +            return "<" + e + ">";
  11.434 +        }
  11.435 +    }
  11.436 +
  11.437 +    /**
  11.438 +     * Invokes the underlying method represented by this {@code Method}
  11.439 +     * object, on the specified object with the specified parameters.
  11.440 +     * Individual parameters are automatically unwrapped to match
  11.441 +     * primitive formal parameters, and both primitive and reference
  11.442 +     * parameters are subject to method invocation conversions as
  11.443 +     * necessary.
  11.444 +     *
  11.445 +     * <p>If the underlying method is static, then the specified {@code obj}
  11.446 +     * argument is ignored. It may be null.
  11.447 +     *
  11.448 +     * <p>If the number of formal parameters required by the underlying method is
  11.449 +     * 0, the supplied {@code args} array may be of length 0 or null.
  11.450 +     *
  11.451 +     * <p>If the underlying method is an instance method, it is invoked
  11.452 +     * using dynamic method lookup as documented in The Java Language
  11.453 +     * Specification, Second Edition, section 15.12.4.4; in particular,
  11.454 +     * overriding based on the runtime type of the target object will occur.
  11.455 +     *
  11.456 +     * <p>If the underlying method is static, the class that declared
  11.457 +     * the method is initialized if it has not already been initialized.
  11.458 +     *
  11.459 +     * <p>If the method completes normally, the value it returns is
  11.460 +     * returned to the caller of invoke; if the value has a primitive
  11.461 +     * type, it is first appropriately wrapped in an object. However,
  11.462 +     * if the value has the type of an array of a primitive type, the
  11.463 +     * elements of the array are <i>not</i> wrapped in objects; in
  11.464 +     * other words, an array of primitive type is returned.  If the
  11.465 +     * underlying method return type is void, the invocation returns
  11.466 +     * null.
  11.467 +     *
  11.468 +     * @param obj  the object the underlying method is invoked from
  11.469 +     * @param args the arguments used for the method call
  11.470 +     * @return the result of dispatching the method represented by
  11.471 +     * this object on {@code obj} with parameters
  11.472 +     * {@code args}
  11.473 +     *
  11.474 +     * @exception IllegalAccessException    if this {@code Method} object
  11.475 +     *              is enforcing Java language access control and the underlying
  11.476 +     *              method is inaccessible.
  11.477 +     * @exception IllegalArgumentException  if the method is an
  11.478 +     *              instance method and the specified object argument
  11.479 +     *              is not an instance of the class or interface
  11.480 +     *              declaring the underlying method (or of a subclass
  11.481 +     *              or implementor thereof); if the number of actual
  11.482 +     *              and formal parameters differ; if an unwrapping
  11.483 +     *              conversion for primitive arguments fails; or if,
  11.484 +     *              after possible unwrapping, a parameter value
  11.485 +     *              cannot be converted to the corresponding formal
  11.486 +     *              parameter type by a method invocation conversion.
  11.487 +     * @exception InvocationTargetException if the underlying method
  11.488 +     *              throws an exception.
  11.489 +     * @exception NullPointerException      if the specified object is null
  11.490 +     *              and the method is an instance method.
  11.491 +     * @exception ExceptionInInitializerError if the initialization
  11.492 +     * provoked by this method fails.
  11.493 +     */
  11.494 +    @JavaScriptBody(args = { "method", "self", "args" }, body =
  11.495 +          "if (args.length > 0) throw 'unsupported now';"
  11.496 +        + "return method.fld_data(self);"
  11.497 +    )
  11.498 +    public Object invoke(Object obj, Object... args)
  11.499 +        throws IllegalAccessException, IllegalArgumentException,
  11.500 +           InvocationTargetException
  11.501 +    {
  11.502 +        throw new UnsupportedOperationException();
  11.503 +    }
  11.504 +
  11.505 +    /**
  11.506 +     * Returns {@code true} if this method is a bridge
  11.507 +     * method; returns {@code false} otherwise.
  11.508 +     *
  11.509 +     * @return true if and only if this method is a bridge
  11.510 +     * method as defined by the Java Language Specification.
  11.511 +     * @since 1.5
  11.512 +     */
  11.513 +    public boolean isBridge() {
  11.514 +        return (getModifiers() & Modifier.BRIDGE) != 0;
  11.515 +    }
  11.516 +
  11.517 +    /**
  11.518 +     * Returns {@code true} if this method was declared to take
  11.519 +     * a variable number of arguments; returns {@code false}
  11.520 +     * otherwise.
  11.521 +     *
  11.522 +     * @return {@code true} if an only if this method was declared to
  11.523 +     * take a variable number of arguments.
  11.524 +     * @since 1.5
  11.525 +     */
  11.526 +    public boolean isVarArgs() {
  11.527 +        return (getModifiers() & Modifier.VARARGS) != 0;
  11.528 +    }
  11.529 +
  11.530 +    /**
  11.531 +     * Returns {@code true} if this method is a synthetic
  11.532 +     * method; returns {@code false} otherwise.
  11.533 +     *
  11.534 +     * @return true if and only if this method is a synthetic
  11.535 +     * method as defined by the Java Language Specification.
  11.536 +     * @since 1.5
  11.537 +     */
  11.538 +    public boolean isSynthetic() {
  11.539 +        return Modifier.isSynthetic(getModifiers());
  11.540 +    }
  11.541 +
  11.542 +    @JavaScriptBody(args = { "self", "ac" }, 
  11.543 +        body = 
  11.544 +          "if (self.fld_data.anno) {"
  11.545 +        + "  return self.fld_data.anno['L' + ac.jvmName + ';'];"
  11.546 +        + "} else return null;"
  11.547 +    )
  11.548 +    private Object getAnnotationData(Class<?> annotationClass) {
  11.549 +        throw new UnsupportedOperationException();
  11.550 +    }
  11.551 +    
  11.552 +    /**
  11.553 +     * @throws NullPointerException {@inheritDoc}
  11.554 +     * @since 1.5
  11.555 +     */
  11.556 +    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  11.557 +        Object data = getAnnotationData(annotationClass);
  11.558 +        return data == null ? null : AnnotationImpl.create(annotationClass, data);
  11.559 +    }
  11.560 +
  11.561 +    /**
  11.562 +     * @since 1.5
  11.563 +     */
  11.564 +    public Annotation[] getDeclaredAnnotations()  {
  11.565 +        throw new UnsupportedOperationException();
  11.566 +    }
  11.567 +
  11.568 +    /**
  11.569 +     * Returns the default value for the annotation member represented by
  11.570 +     * this {@code Method} instance.  If the member is of a primitive type,
  11.571 +     * an instance of the corresponding wrapper type is returned. Returns
  11.572 +     * null if no default is associated with the member, or if the method
  11.573 +     * instance does not represent a declared member of an annotation type.
  11.574 +     *
  11.575 +     * @return the default value for the annotation member represented
  11.576 +     *     by this {@code Method} instance.
  11.577 +     * @throws TypeNotPresentException if the annotation is of type
  11.578 +     *     {@link Class} and no definition can be found for the
  11.579 +     *     default class value.
  11.580 +     * @since  1.5
  11.581 +     */
  11.582 +    public Object getDefaultValue() {
  11.583 +        throw new UnsupportedOperationException();
  11.584 +    }
  11.585 +
  11.586 +    /**
  11.587 +     * Returns an array of arrays that represent the annotations on the formal
  11.588 +     * parameters, in declaration order, of the method represented by
  11.589 +     * this {@code Method} object. (Returns an array of length zero if the
  11.590 +     * underlying method is parameterless.  If the method has one or more
  11.591 +     * parameters, a nested array of length zero is returned for each parameter
  11.592 +     * with no annotations.) The annotation objects contained in the returned
  11.593 +     * arrays are serializable.  The caller of this method is free to modify
  11.594 +     * the returned arrays; it will have no effect on the arrays returned to
  11.595 +     * other callers.
  11.596 +     *
  11.597 +     * @return an array of arrays that represent the annotations on the formal
  11.598 +     *    parameters, in declaration order, of the method represented by this
  11.599 +     *    Method object
  11.600 +     * @since 1.5
  11.601 +     */
  11.602 +    public Annotation[][] getParameterAnnotations() {
  11.603 +        throw new UnsupportedOperationException();
  11.604 +    }
  11.605 +    
  11.606 +    //
  11.607 +    // bck2brwsr implementation
  11.608 +    //
  11.609 +
  11.610 +    @JavaScriptBody(args = { "clazz", "prefix" },
  11.611 +        body = ""
  11.612 +        + "var c = clazz.cnstr.prototype;"
  11.613 +        + "var arr = new Array();\n"
  11.614 +        + "for (m in c) {\n"
  11.615 +        + "  if (m.indexOf(prefix) === 0) {\n"
  11.616 +        + "     arr.push(m);\n"
  11.617 +        + "     arr.push(c[m]);\n"
  11.618 +        + "  }"
  11.619 +        + "}\n"
  11.620 +        + "return arr;"
  11.621 +    )
  11.622 +    private static native Object[] findMethodData(
  11.623 +        Class<?> clazz, String prefix
  11.624 +    );
  11.625 +
  11.626 +    // XXX should not be public
  11.627 +    public static Method findMethod(
  11.628 +        Class<?> clazz, String name, Class<?>... parameterTypes
  11.629 +    ) {
  11.630 +        Object[] data = findMethodData(clazz, name + "__");
  11.631 +        if (data.length == 0) {
  11.632 +            return null;
  11.633 +        }
  11.634 +        String sig = ((String)data[0]).substring(name.length() + 2);
  11.635 +        return new Method(clazz, name, data[1], sig);
  11.636 +    }
  11.637 +    
  11.638 +    public static Method[] findMethods(Class<?> clazz) {
  11.639 +        Object[] namesAndData = findMethodData(clazz, "");
  11.640 +        int cnt = 0;
  11.641 +        for (int i = 0; i < namesAndData.length; i += 2) {
  11.642 +            String sig = (String) namesAndData[i];
  11.643 +            Object data = namesAndData[i + 1];
  11.644 +            int middle = sig.indexOf("__");
  11.645 +            if (middle == -1) {
  11.646 +                continue;
  11.647 +            }
  11.648 +            String name = sig.substring(0, middle);
  11.649 +            sig = sig.substring(middle + 2);
  11.650 +            namesAndData[cnt++] = new Method(clazz, name, data, sig);
  11.651 +        }
  11.652 +        Method[] arr = new Method[cnt];
  11.653 +        for (int i = 0; i < cnt; i++) {
  11.654 +            arr[i] = (Method)namesAndData[i];
  11.655 +        }
  11.656 +        return arr;
  11.657 +    }
  11.658 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/emul/src/main/java/java/lang/reflect/Modifier.java	Wed Dec 12 12:41:06 2012 +0100
    12.3 @@ -0,0 +1,437 @@
    12.4 +/*
    12.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.  Oracle designates this
   12.11 + * particular file as subject to the "Classpath" exception as provided
   12.12 + * by Oracle in the LICENSE file that accompanied this code.
   12.13 + *
   12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.17 + * version 2 for more details (a copy is included in the LICENSE file that
   12.18 + * accompanied this code).
   12.19 + *
   12.20 + * You should have received a copy of the GNU General Public License version
   12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.23 + *
   12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.25 + * or visit www.oracle.com if you need additional information or have any
   12.26 + * questions.
   12.27 + */
   12.28 +
   12.29 +package java.lang.reflect;
   12.30 +
   12.31 +/**
   12.32 + * The Modifier class provides {@code static} methods and
   12.33 + * constants to decode class and member access modifiers.  The sets of
   12.34 + * modifiers are represented as integers with distinct bit positions
   12.35 + * representing different modifiers.  The values for the constants
   12.36 + * representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of
   12.37 + * <cite>The Java&trade; Virtual Machine Specification</cite>.
   12.38 + *
   12.39 + * @see Class#getModifiers()
   12.40 + * @see Member#getModifiers()
   12.41 + *
   12.42 + * @author Nakul Saraiya
   12.43 + * @author Kenneth Russell
   12.44 + */
   12.45 +public
   12.46 +class Modifier {
   12.47 +
   12.48 +    /**
   12.49 +     * Return {@code true} if the integer argument includes the
   12.50 +     * {@code public} modifier, {@code false} otherwise.
   12.51 +     *
   12.52 +     * @param   mod a set of modifiers
   12.53 +     * @return {@code true} if {@code mod} includes the
   12.54 +     * {@code public} modifier; {@code false} otherwise.
   12.55 +     */
   12.56 +    public static boolean isPublic(int mod) {
   12.57 +        return (mod & PUBLIC) != 0;
   12.58 +    }
   12.59 +
   12.60 +    /**
   12.61 +     * Return {@code true} if the integer argument includes the
   12.62 +     * {@code private} modifier, {@code false} otherwise.
   12.63 +     *
   12.64 +     * @param   mod a set of modifiers
   12.65 +     * @return {@code true} if {@code mod} includes the
   12.66 +     * {@code private} modifier; {@code false} otherwise.
   12.67 +     */
   12.68 +    public static boolean isPrivate(int mod) {
   12.69 +        return (mod & PRIVATE) != 0;
   12.70 +    }
   12.71 +
   12.72 +    /**
   12.73 +     * Return {@code true} if the integer argument includes the
   12.74 +     * {@code protected} modifier, {@code false} otherwise.
   12.75 +     *
   12.76 +     * @param   mod a set of modifiers
   12.77 +     * @return {@code true} if {@code mod} includes the
   12.78 +     * {@code protected} modifier; {@code false} otherwise.
   12.79 +     */
   12.80 +    public static boolean isProtected(int mod) {
   12.81 +        return (mod & PROTECTED) != 0;
   12.82 +    }
   12.83 +
   12.84 +    /**
   12.85 +     * Return {@code true} if the integer argument includes the
   12.86 +     * {@code static} modifier, {@code false} otherwise.
   12.87 +     *
   12.88 +     * @param   mod a set of modifiers
   12.89 +     * @return {@code true} if {@code mod} includes the
   12.90 +     * {@code static} modifier; {@code false} otherwise.
   12.91 +     */
   12.92 +    public static boolean isStatic(int mod) {
   12.93 +        return (mod & STATIC) != 0;
   12.94 +    }
   12.95 +
   12.96 +    /**
   12.97 +     * Return {@code true} if the integer argument includes the
   12.98 +     * {@code final} modifier, {@code false} otherwise.
   12.99 +     *
  12.100 +     * @param   mod a set of modifiers
  12.101 +     * @return {@code true} if {@code mod} includes the
  12.102 +     * {@code final} modifier; {@code false} otherwise.
  12.103 +     */
  12.104 +    public static boolean isFinal(int mod) {
  12.105 +        return (mod & FINAL) != 0;
  12.106 +    }
  12.107 +
  12.108 +    /**
  12.109 +     * Return {@code true} if the integer argument includes the
  12.110 +     * {@code synchronized} modifier, {@code false} otherwise.
  12.111 +     *
  12.112 +     * @param   mod a set of modifiers
  12.113 +     * @return {@code true} if {@code mod} includes the
  12.114 +     * {@code synchronized} modifier; {@code false} otherwise.
  12.115 +     */
  12.116 +    public static boolean isSynchronized(int mod) {
  12.117 +        return (mod & SYNCHRONIZED) != 0;
  12.118 +    }
  12.119 +
  12.120 +    /**
  12.121 +     * Return {@code true} if the integer argument includes the
  12.122 +     * {@code volatile} modifier, {@code false} otherwise.
  12.123 +     *
  12.124 +     * @param   mod a set of modifiers
  12.125 +     * @return {@code true} if {@code mod} includes the
  12.126 +     * {@code volatile} modifier; {@code false} otherwise.
  12.127 +     */
  12.128 +    public static boolean isVolatile(int mod) {
  12.129 +        return (mod & VOLATILE) != 0;
  12.130 +    }
  12.131 +
  12.132 +    /**
  12.133 +     * Return {@code true} if the integer argument includes the
  12.134 +     * {@code transient} modifier, {@code false} otherwise.
  12.135 +     *
  12.136 +     * @param   mod a set of modifiers
  12.137 +     * @return {@code true} if {@code mod} includes the
  12.138 +     * {@code transient} modifier; {@code false} otherwise.
  12.139 +     */
  12.140 +    public static boolean isTransient(int mod) {
  12.141 +        return (mod & TRANSIENT) != 0;
  12.142 +    }
  12.143 +
  12.144 +    /**
  12.145 +     * Return {@code true} if the integer argument includes the
  12.146 +     * {@code native} modifier, {@code false} otherwise.
  12.147 +     *
  12.148 +     * @param   mod a set of modifiers
  12.149 +     * @return {@code true} if {@code mod} includes the
  12.150 +     * {@code native} modifier; {@code false} otherwise.
  12.151 +     */
  12.152 +    public static boolean isNative(int mod) {
  12.153 +        return (mod & NATIVE) != 0;
  12.154 +    }
  12.155 +
  12.156 +    /**
  12.157 +     * Return {@code true} if the integer argument includes the
  12.158 +     * {@code interface} modifier, {@code false} otherwise.
  12.159 +     *
  12.160 +     * @param   mod a set of modifiers
  12.161 +     * @return {@code true} if {@code mod} includes the
  12.162 +     * {@code interface} modifier; {@code false} otherwise.
  12.163 +     */
  12.164 +    public static boolean isInterface(int mod) {
  12.165 +        return (mod & INTERFACE) != 0;
  12.166 +    }
  12.167 +
  12.168 +    /**
  12.169 +     * Return {@code true} if the integer argument includes the
  12.170 +     * {@code abstract} modifier, {@code false} otherwise.
  12.171 +     *
  12.172 +     * @param   mod a set of modifiers
  12.173 +     * @return {@code true} if {@code mod} includes the
  12.174 +     * {@code abstract} modifier; {@code false} otherwise.
  12.175 +     */
  12.176 +    public static boolean isAbstract(int mod) {
  12.177 +        return (mod & ABSTRACT) != 0;
  12.178 +    }
  12.179 +
  12.180 +    /**
  12.181 +     * Return {@code true} if the integer argument includes the
  12.182 +     * {@code strictfp} modifier, {@code false} otherwise.
  12.183 +     *
  12.184 +     * @param   mod a set of modifiers
  12.185 +     * @return {@code true} if {@code mod} includes the
  12.186 +     * {@code strictfp} modifier; {@code false} otherwise.
  12.187 +     */
  12.188 +    public static boolean isStrict(int mod) {
  12.189 +        return (mod & STRICT) != 0;
  12.190 +    }
  12.191 +
  12.192 +    /**
  12.193 +     * Return a string describing the access modifier flags in
  12.194 +     * the specified modifier. For example:
  12.195 +     * <blockquote><pre>
  12.196 +     *    public final synchronized strictfp
  12.197 +     * </pre></blockquote>
  12.198 +     * The modifier names are returned in an order consistent with the
  12.199 +     * suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of
  12.200 +     * <cite>The Java&trade; Language Specification</cite>.
  12.201 +     * The full modifier ordering used by this method is:
  12.202 +     * <blockquote> {@code
  12.203 +     * public protected private abstract static final transient
  12.204 +     * volatile synchronized native strictfp
  12.205 +     * interface } </blockquote>
  12.206 +     * The {@code interface} modifier discussed in this class is
  12.207 +     * not a true modifier in the Java language and it appears after
  12.208 +     * all other modifiers listed by this method.  This method may
  12.209 +     * return a string of modifiers that are not valid modifiers of a
  12.210 +     * Java entity; in other words, no checking is done on the
  12.211 +     * possible validity of the combination of modifiers represented
  12.212 +     * by the input.
  12.213 +     *
  12.214 +     * Note that to perform such checking for a known kind of entity,
  12.215 +     * such as a constructor or method, first AND the argument of
  12.216 +     * {@code toString} with the appropriate mask from a method like
  12.217 +     * {@link #constructorModifiers} or {@link #methodModifiers}.
  12.218 +     *
  12.219 +     * @param   mod a set of modifiers
  12.220 +     * @return  a string representation of the set of modifiers
  12.221 +     * represented by {@code mod}
  12.222 +     */
  12.223 +    public static String toString(int mod) {
  12.224 +        StringBuffer sb = new StringBuffer();
  12.225 +        int len;
  12.226 +
  12.227 +        if ((mod & PUBLIC) != 0)        sb.append("public ");
  12.228 +        if ((mod & PROTECTED) != 0)     sb.append("protected ");
  12.229 +        if ((mod & PRIVATE) != 0)       sb.append("private ");
  12.230 +
  12.231 +        /* Canonical order */
  12.232 +        if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
  12.233 +        if ((mod & STATIC) != 0)        sb.append("static ");
  12.234 +        if ((mod & FINAL) != 0)         sb.append("final ");
  12.235 +        if ((mod & TRANSIENT) != 0)     sb.append("transient ");
  12.236 +        if ((mod & VOLATILE) != 0)      sb.append("volatile ");
  12.237 +        if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
  12.238 +        if ((mod & NATIVE) != 0)        sb.append("native ");
  12.239 +        if ((mod & STRICT) != 0)        sb.append("strictfp ");
  12.240 +        if ((mod & INTERFACE) != 0)     sb.append("interface ");
  12.241 +
  12.242 +        if ((len = sb.length()) > 0)    /* trim trailing space */
  12.243 +            return sb.toString().substring(0, len-1);
  12.244 +        return "";
  12.245 +    }
  12.246 +
  12.247 +    /*
  12.248 +     * Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of
  12.249 +     * <cite>The Java&trade; Virtual Machine Specification</cite>
  12.250 +     */
  12.251 +
  12.252 +    /**
  12.253 +     * The {@code int} value representing the {@code public}
  12.254 +     * modifier.
  12.255 +     */
  12.256 +    public static final int PUBLIC           = 0x00000001;
  12.257 +
  12.258 +    /**
  12.259 +     * The {@code int} value representing the {@code private}
  12.260 +     * modifier.
  12.261 +     */
  12.262 +    public static final int PRIVATE          = 0x00000002;
  12.263 +
  12.264 +    /**
  12.265 +     * The {@code int} value representing the {@code protected}
  12.266 +     * modifier.
  12.267 +     */
  12.268 +    public static final int PROTECTED        = 0x00000004;
  12.269 +
  12.270 +    /**
  12.271 +     * The {@code int} value representing the {@code static}
  12.272 +     * modifier.
  12.273 +     */
  12.274 +    public static final int STATIC           = 0x00000008;
  12.275 +
  12.276 +    /**
  12.277 +     * The {@code int} value representing the {@code final}
  12.278 +     * modifier.
  12.279 +     */
  12.280 +    public static final int FINAL            = 0x00000010;
  12.281 +
  12.282 +    /**
  12.283 +     * The {@code int} value representing the {@code synchronized}
  12.284 +     * modifier.
  12.285 +     */
  12.286 +    public static final int SYNCHRONIZED     = 0x00000020;
  12.287 +
  12.288 +    /**
  12.289 +     * The {@code int} value representing the {@code volatile}
  12.290 +     * modifier.
  12.291 +     */
  12.292 +    public static final int VOLATILE         = 0x00000040;
  12.293 +
  12.294 +    /**
  12.295 +     * The {@code int} value representing the {@code transient}
  12.296 +     * modifier.
  12.297 +     */
  12.298 +    public static final int TRANSIENT        = 0x00000080;
  12.299 +
  12.300 +    /**
  12.301 +     * The {@code int} value representing the {@code native}
  12.302 +     * modifier.
  12.303 +     */
  12.304 +    public static final int NATIVE           = 0x00000100;
  12.305 +
  12.306 +    /**
  12.307 +     * The {@code int} value representing the {@code interface}
  12.308 +     * modifier.
  12.309 +     */
  12.310 +    public static final int INTERFACE        = 0x00000200;
  12.311 +
  12.312 +    /**
  12.313 +     * The {@code int} value representing the {@code abstract}
  12.314 +     * modifier.
  12.315 +     */
  12.316 +    public static final int ABSTRACT         = 0x00000400;
  12.317 +
  12.318 +    /**
  12.319 +     * The {@code int} value representing the {@code strictfp}
  12.320 +     * modifier.
  12.321 +     */
  12.322 +    public static final int STRICT           = 0x00000800;
  12.323 +
  12.324 +    // Bits not (yet) exposed in the public API either because they
  12.325 +    // have different meanings for fields and methods and there is no
  12.326 +    // way to distinguish between the two in this class, or because
  12.327 +    // they are not Java programming language keywords
  12.328 +    static final int BRIDGE    = 0x00000040;
  12.329 +    static final int VARARGS   = 0x00000080;
  12.330 +    static final int SYNTHETIC = 0x00001000;
  12.331 +    static final int ANNOTATION= 0x00002000;
  12.332 +    static final int ENUM      = 0x00004000;
  12.333 +    static boolean isSynthetic(int mod) {
  12.334 +      return (mod & SYNTHETIC) != 0;
  12.335 +    }
  12.336 +
  12.337 +    /**
  12.338 +     * See JLSv3 section 8.1.1.
  12.339 +     */
  12.340 +    private static final int CLASS_MODIFIERS =
  12.341 +        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
  12.342 +        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.FINAL   |
  12.343 +        Modifier.STRICT;
  12.344 +
  12.345 +    /**
  12.346 +     * See JLSv3 section 9.1.1.
  12.347 +     */
  12.348 +    private static final int INTERFACE_MODIFIERS =
  12.349 +        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
  12.350 +        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.STRICT;
  12.351 +
  12.352 +
  12.353 +    /**
  12.354 +     * See JLSv3 section 8.8.3.
  12.355 +     */
  12.356 +    private static final int CONSTRUCTOR_MODIFIERS =
  12.357 +        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE;
  12.358 +
  12.359 +    /**
  12.360 +     * See JLSv3 section 8.4.3.
  12.361 +     */
  12.362 +    private static final int METHOD_MODIFIERS =
  12.363 +        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
  12.364 +        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.FINAL   |
  12.365 +        Modifier.SYNCHRONIZED   | Modifier.NATIVE       | Modifier.STRICT;
  12.366 +
  12.367 +    /**
  12.368 +     * See JLSv3 section 8.3.1.
  12.369 +     */
  12.370 +    private static final int FIELD_MODIFIERS =
  12.371 +        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
  12.372 +        Modifier.STATIC         | Modifier.FINAL        | Modifier.TRANSIENT |
  12.373 +        Modifier.VOLATILE;
  12.374 +
  12.375 +    /**
  12.376 +     * Return an {@code int} value OR-ing together the source language
  12.377 +     * modifiers that can be applied to a class.
  12.378 +     * @return an {@code int} value OR-ing together the source language
  12.379 +     * modifiers that can be applied to a class.
  12.380 +     *
  12.381 +     * @jls 8.1.1 Class Modifiers
  12.382 +     * @since 1.7
  12.383 +     */
  12.384 +    public static int classModifiers() {
  12.385 +        return CLASS_MODIFIERS;
  12.386 +    }
  12.387 +
  12.388 +    /**
  12.389 +     * Return an {@code int} value OR-ing together the source language
  12.390 +     * modifiers that can be applied to an interface.
  12.391 +     * @return an {@code int} value OR-ing together the source language
  12.392 +     * modifiers that can be applied to an inteface.
  12.393 +     *
  12.394 +     * @jls 9.1.1 Interface Modifiers
  12.395 +     * @since 1.7
  12.396 +     */
  12.397 +    public static int interfaceModifiers() {
  12.398 +        return INTERFACE_MODIFIERS;
  12.399 +    }
  12.400 +
  12.401 +    /**
  12.402 +     * Return an {@code int} value OR-ing together the source language
  12.403 +     * modifiers that can be applied to a constructor.
  12.404 +     * @return an {@code int} value OR-ing together the source language
  12.405 +     * modifiers that can be applied to a constructor.
  12.406 +     *
  12.407 +     * @jls 8.8.3 Constructor Modifiers
  12.408 +     * @since 1.7
  12.409 +     */
  12.410 +    public static int constructorModifiers() {
  12.411 +        return CONSTRUCTOR_MODIFIERS;
  12.412 +    }
  12.413 +
  12.414 +    /**
  12.415 +     * Return an {@code int} value OR-ing together the source language
  12.416 +     * modifiers that can be applied to a method.
  12.417 +     * @return an {@code int} value OR-ing together the source language
  12.418 +     * modifiers that can be applied to a method.
  12.419 +     *
  12.420 +     * @jls 8.4.3 Method Modifiers
  12.421 +     * @since 1.7
  12.422 +     */
  12.423 +    public static int methodModifiers() {
  12.424 +        return METHOD_MODIFIERS;
  12.425 +    }
  12.426 +
  12.427 +
  12.428 +    /**
  12.429 +     * Return an {@code int} value OR-ing together the source language
  12.430 +     * modifiers that can be applied to a field.
  12.431 +     * @return an {@code int} value OR-ing together the source language
  12.432 +     * modifiers that can be applied to a field.
  12.433 +     *
  12.434 +     * @jls 8.3.1 Field Modifiers
  12.435 +     * @since 1.7
  12.436 +     */
  12.437 +    public static int fieldModifiers() {
  12.438 +        return FIELD_MODIFIERS;
  12.439 +    }
  12.440 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/emul/src/main/java/java/lang/reflect/Type.java	Wed Dec 12 12:41:06 2012 +0100
    13.3 @@ -0,0 +1,37 @@
    13.4 +/*
    13.5 + * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.  Oracle designates this
   13.11 + * particular file as subject to the "Classpath" exception as provided
   13.12 + * by Oracle in the LICENSE file that accompanied this code.
   13.13 + *
   13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 + * version 2 for more details (a copy is included in the LICENSE file that
   13.18 + * accompanied this code).
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License version
   13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 + *
   13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 + * or visit www.oracle.com if you need additional information or have any
   13.26 + * questions.
   13.27 + */
   13.28 +
   13.29 +package java.lang.reflect;
   13.30 +
   13.31 +/**
   13.32 + * Type is the common superinterface for all types in the Java
   13.33 + * programming language. These include raw types, parameterized types,
   13.34 + * array types, type variables and primitive types.
   13.35 + *
   13.36 + * @since 1.5
   13.37 + */
   13.38 +
   13.39 +public interface Type {
   13.40 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/emul/src/main/java/java/lang/reflect/TypeVariable.java	Wed Dec 12 12:41:06 2012 +0100
    14.3 @@ -0,0 +1,89 @@
    14.4 +/*
    14.5 + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.  Oracle designates this
   14.11 + * particular file as subject to the "Classpath" exception as provided
   14.12 + * by Oracle in the LICENSE file that accompanied this code.
   14.13 + *
   14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.17 + * version 2 for more details (a copy is included in the LICENSE file that
   14.18 + * accompanied this code).
   14.19 + *
   14.20 + * You should have received a copy of the GNU General Public License version
   14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.23 + *
   14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.25 + * or visit www.oracle.com if you need additional information or have any
   14.26 + * questions.
   14.27 + */
   14.28 +
   14.29 +package java.lang.reflect;
   14.30 +
   14.31 +/**
   14.32 + * TypeVariable is the common superinterface for type variables of kinds.
   14.33 + * A type variable is created the first time it is needed by a reflective
   14.34 + * method, as specified in this package.  If a type variable t is referenced
   14.35 + * by a type (i.e, class, interface or annotation type) T, and T is declared
   14.36 + * by the nth enclosing class of T (see JLS 8.1.2), then the creation of t
   14.37 + * requires the resolution (see JVMS 5) of the ith enclosing class of T,
   14.38 + * for i = 0 to n, inclusive. Creating a type variable must not cause the
   14.39 + * creation of its bounds. Repeated creation of a type variable has no effect.
   14.40 + *
   14.41 + * <p>Multiple objects may be instantiated at run-time to
   14.42 + * represent a given type variable. Even though a type variable is
   14.43 + * created only once, this does not imply any requirement to cache
   14.44 + * instances representing the type variable. However, all instances
   14.45 + * representing a type variable must be equal() to each other.
   14.46 + * As a consequence, users of type variables must not rely on the identity
   14.47 + * of instances of classes implementing this interface.
   14.48 + *
   14.49 + * @param <D> the type of generic declaration that declared the
   14.50 + * underlying type variable.
   14.51 + *
   14.52 + * @since 1.5
   14.53 + */
   14.54 +public interface TypeVariable<D extends GenericDeclaration> extends Type {
   14.55 +    /**
   14.56 +     * Returns an array of {@code Type} objects representing the
   14.57 +     * upper bound(s) of this type variable.  Note that if no upper bound is
   14.58 +     * explicitly declared, the upper bound is {@code Object}.
   14.59 +     *
   14.60 +     * <p>For each upper bound B: <ul> <li>if B is a parameterized
   14.61 +     * type or a type variable, it is created, (see {@link
   14.62 +     * java.lang.reflect.ParameterizedType ParameterizedType} for the
   14.63 +     * details of the creation process for parameterized types).
   14.64 +     * <li>Otherwise, B is resolved.  </ul>
   14.65 +     *
   14.66 +     * @throws TypeNotPresentException  if any of the
   14.67 +     *     bounds refers to a non-existent type declaration
   14.68 +     * @throws MalformedParameterizedTypeException if any of the
   14.69 +     *     bounds refer to a parameterized type that cannot be instantiated
   14.70 +     *     for any reason
   14.71 +     * @return an array of {@code Type}s representing the upper
   14.72 +     *     bound(s) of this type variable
   14.73 +    */
   14.74 +    Type[] getBounds();
   14.75 +
   14.76 +    /**
   14.77 +     * Returns the {@code GenericDeclaration} object representing the
   14.78 +     * generic declaration declared this type variable.
   14.79 +     *
   14.80 +     * @return the generic declaration declared for this type variable.
   14.81 +     *
   14.82 +     * @since 1.5
   14.83 +     */
   14.84 +    D getGenericDeclaration();
   14.85 +
   14.86 +    /**
   14.87 +     * Returns the name of this type variable, as it occurs in the source code.
   14.88 +     *
   14.89 +     * @return the name of this type variable, as it appears in the source code
   14.90 +     */
   14.91 +    String getName();
   14.92 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/emul/src/main/java/java/lang/reflect/package-info.java	Wed Dec 12 12:41:06 2012 +0100
    15.3 @@ -0,0 +1,49 @@
    15.4 +/*
    15.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.  Oracle designates this
   15.11 + * particular file as subject to the "Classpath" exception as provided
   15.12 + * by Oracle in the LICENSE file that accompanied this code.
   15.13 + *
   15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.17 + * version 2 for more details (a copy is included in the LICENSE file that
   15.18 + * accompanied this code).
   15.19 + *
   15.20 + * You should have received a copy of the GNU General Public License version
   15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.23 + *
   15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.25 + * or visit www.oracle.com if you need additional information or have any
   15.26 + * questions.
   15.27 + */
   15.28 +
   15.29 +/**
   15.30 + * Provides classes and interfaces for obtaining reflective
   15.31 + * information about classes and objects.  Reflection allows
   15.32 + * programmatic access to information about the fields, methods and
   15.33 + * constructors of loaded classes, and the use of reflected fields,
   15.34 + * methods, and constructors to operate on their underlying
   15.35 + * counterparts, within security restrictions.
   15.36 + *
   15.37 + * <p>{@code AccessibleObject} allows suppression of access checks if
   15.38 + * the necessary {@code ReflectPermission} is available.
   15.39 + *
   15.40 + * <p>{@code Array} provides static methods to dynamically create and
   15.41 + * access arrays.
   15.42 + *
   15.43 + * <p>Classes in this package, along with {@code java.lang.Class}
   15.44 + * accommodate applications such as debuggers, interpreters, object
   15.45 + * inspectors, class browsers, and services such as Object
   15.46 + * Serialization and JavaBeans that need access to either the public
   15.47 + * members of a target object (based on its runtime class) or the
   15.48 + * members declared by a given class.
   15.49 + *
   15.50 + * @since JDK1.1
   15.51 + */
   15.52 +package java.lang.reflect;
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/AnnotationImpl.java	Wed Dec 12 12:41:06 2012 +0100
    16.3 @@ -0,0 +1,68 @@
    16.4 +/*
    16.5 + * To change this template, choose Tools | Templates
    16.6 + * and open the template in the editor.
    16.7 + */
    16.8 +package org.apidesign.bck2brwsr.emul;
    16.9 +
   16.10 +import java.lang.annotation.Annotation;
   16.11 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   16.12 +
   16.13 +/**
   16.14 + *
   16.15 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   16.16 + */
   16.17 +public final class AnnotationImpl implements Annotation {
   16.18 +    public Class<? extends Annotation> annotationType() {
   16.19 +        return getClass();
   16.20 +    }
   16.21 +
   16.22 +    @JavaScriptBody(args = { "a", "n", "values" }, body = ""
   16.23 +        + "function f(v, p) {\n"
   16.24 +        + "  var val = v;\n"
   16.25 +        + "  var prop = p;\n"
   16.26 +        + "  return function() {\n"
   16.27 +        + "    return val[prop];\n"
   16.28 +        + "  };\n"
   16.29 +        + "}\n"
   16.30 +        + "var props = Object.getOwnPropertyNames(values);\n"
   16.31 +        + "for (var i = 0; i < props.length; i++) {\n"
   16.32 +        + "  var p = props[i];\n"
   16.33 +        + "  a[p] = new f(values, p);\n"
   16.34 +        + "}\n"
   16.35 +        + "a['$instOf_' + n] = true;\n"
   16.36 +        + "return a;"
   16.37 +    )
   16.38 +    private static <T extends Annotation> T create(AnnotationImpl a, String n, Object values) {
   16.39 +        return null;
   16.40 +    }
   16.41 +    public static <T extends Annotation> T create(Class<T> annoClass, Object values) {
   16.42 +        return create(new AnnotationImpl(), annoClass.getName().replace('.', '_'), values);
   16.43 +    }
   16.44 +
   16.45 +    public static Annotation[] create(Object anno) {
   16.46 +        String[] names = findNames(anno);
   16.47 +        Annotation[] ret = new Annotation[names.length];
   16.48 +        for (int i = 0; i < names.length; i++) {
   16.49 +            String n = names[i].substring(1, names[i].length() - 1).replace('/', '_');
   16.50 +            ret[i] = create(new AnnotationImpl(), n, findData(anno, names[i]));
   16.51 +        }
   16.52 +        return ret;
   16.53 +    }
   16.54 +    @JavaScriptBody(args = "anno", body =
   16.55 +          "var arr = new Array();"
   16.56 +        + "var props = Object.getOwnPropertyNames(anno);\n"
   16.57 +        + "for (var i = 0; i < props.length; i++) {\n"
   16.58 +        + "  var p = props[i];\n"
   16.59 +        + "  arr.push(p);"
   16.60 +        + "}"
   16.61 +        + "return arr;"
   16.62 +    )
   16.63 +    private static String[] findNames(Object anno) {
   16.64 +        throw new UnsupportedOperationException();
   16.65 +    }
   16.66 +
   16.67 +    @JavaScriptBody(args={ "anno", "p"}, body="return anno[p];")
   16.68 +    private static Object findData(Object anno, String p) {
   16.69 +        throw new UnsupportedOperationException();
   16.70 +    }
   16.71 +}
    17.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Wed Dec 12 12:37:41 2012 +0100
    17.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Wed Dec 12 12:41:06 2012 +0100
    17.3 @@ -1,2 +1,9 @@
    17.4  // initialize methods on String constants
    17.5 -java_lang_String(false)
    17.6 +vm.java_lang_String(false);
    17.7 +
    17.8 +// we need initialized arrays
    17.9 +Array.prototype.fillNulls = function() {
   17.10 +  for(var i = 0; i < this.length; i++) this[i] = null;
   17.11 +  return this;
   17.12 +};
   17.13 +
    18.1 --- a/javap/src/main/java/org/apidesign/javap/AnnotationParser.java	Wed Dec 12 12:37:41 2012 +0100
    18.2 +++ b/javap/src/main/java/org/apidesign/javap/AnnotationParser.java	Wed Dec 12 12:41:06 2012 +0100
    18.3 @@ -34,10 +34,21 @@
    18.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
    18.5   */
    18.6  public class AnnotationParser {
    18.7 -    protected AnnotationParser() {
    18.8 +    private final boolean textual;
    18.9 +    
   18.10 +    protected AnnotationParser(boolean textual) {
   18.11 +        this.textual = textual;
   18.12      }
   18.13  
   18.14 -    protected void visitAttr(String type, String attr, String value) {
   18.15 +    protected void visitAnnotationStart(String type) throws IOException {
   18.16 +    }
   18.17 +
   18.18 +    protected void visitAnnotationEnd(String type) throws IOException {
   18.19 +    }
   18.20 +    
   18.21 +    protected void visitAttr(
   18.22 +        String annoType, String attr, String attrType, String value
   18.23 +    ) throws IOException {
   18.24      }
   18.25      
   18.26      /** Initialize the parsing with constant pool from <code>cd</code>.
   18.27 @@ -66,13 +77,15 @@
   18.28      private void readAnno(DataInputStream dis, ClassData cd) throws IOException {
   18.29          int type = dis.readUnsignedShort();
   18.30          String typeName = cd.StringValue(type);
   18.31 +        visitAnnotationStart(typeName);
   18.32      	int cnt = dis.readUnsignedShort();
   18.33      	for (int i = 0; i < cnt; i++) {
   18.34              String attrName = cd.StringValue(dis.readUnsignedShort());
   18.35              readValue(dis, cd, typeName, attrName);
   18.36          }
   18.37 +        visitAnnotationEnd(typeName);
   18.38          if (cnt == 0) {
   18.39 -            visitAttr(typeName, null, null);
   18.40 +            visitAttr(typeName, null, null, null);
   18.41          }
   18.42      }
   18.43  
   18.44 @@ -83,7 +96,17 @@
   18.45              readAnno(dis, cd);
   18.46          } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
   18.47              int primitive = dis.readUnsignedShort();
   18.48 -            visitAttr(typeName, attrName, cd.StringValue(primitive));
   18.49 +            String val = cd.stringValue(primitive, textual);
   18.50 +            String attrType;
   18.51 +            if (type == 's') {
   18.52 +                attrType = "Ljava_lang_String_2";
   18.53 +                if (textual) {
   18.54 +                    val = '"' + val + '"';
   18.55 +                }
   18.56 +            } else {
   18.57 +                attrType = "" + type;
   18.58 +            }
   18.59 +            visitAttr(typeName, attrName, attrType, val);
   18.60          } else if (type == 'c') {
   18.61              int cls = dis.readUnsignedShort();
   18.62          } else if (type == '[') {
    19.1 --- a/javap/src/main/java/org/apidesign/javap/ClassData.java	Wed Dec 12 12:37:41 2012 +0100
    19.2 +++ b/javap/src/main/java/org/apidesign/javap/ClassData.java	Wed Dec 12 12:41:06 2012 +0100
    19.3 @@ -488,6 +488,12 @@
    19.4          return stringValue(cpx, false);
    19.5      }
    19.6      public String stringValue(int cpx, boolean textual) {
    19.7 +        return stringValue(cpx, textual, null);
    19.8 +    }
    19.9 +    public String stringValue(int cpx, String[] classRefs) {
   19.10 +        return stringValue(cpx, true, classRefs);
   19.11 +    }
   19.12 +    private String stringValue(int cpx, boolean textual, String[] refs) {
   19.13          if (cpx==0) return "#0";
   19.14          int tag;
   19.15          Object x;
   19.16 @@ -548,10 +554,14 @@
   19.17              return in.toString();
   19.18          }
   19.19          case CONSTANT_CLASS:
   19.20 +            String jn = getClassName(cpx);
   19.21              if (textual) {
   19.22 -                return "new java_lang_Class"; // XXX temporary JS
   19.23 +                if (refs != null) {
   19.24 +                    refs[0] = jn;
   19.25 +                }
   19.26 +                return jn;
   19.27              }
   19.28 -            return javaName(getClassName(cpx));
   19.29 +            return javaName(jn);
   19.30          case CONSTANT_STRING:
   19.31              String sv = stringValue(((CPX)x).cpx, textual);
   19.32              if (textual) {
    20.1 --- a/javap/src/main/java/org/apidesign/javap/FieldData.java	Wed Dec 12 12:37:41 2012 +0100
    20.2 +++ b/javap/src/main/java/org/apidesign/javap/FieldData.java	Wed Dec 12 12:41:06 2012 +0100
    20.3 @@ -130,13 +130,6 @@
    20.4      }
    20.5  
    20.6      /**
    20.7 -     * Returns java type signature of a field.
    20.8 -     */
    20.9 -    public String getType(){
   20.10 -        return new TypeSignature(getInternalSig()).getFieldType();
   20.11 -    }
   20.12 -
   20.13 -    /**
   20.14       * Returns true if field is synthetic.
   20.15       */
   20.16      public boolean isSynthetic(){
    21.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java	Wed Dec 12 12:37:41 2012 +0100
    21.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java	Wed Dec 12 12:41:06 2012 +0100
    21.3 @@ -268,24 +268,6 @@
    21.4      }
    21.5  
    21.6      /**
    21.7 -     * Return java return type signature of method.
    21.8 -     */
    21.9 -    public String getReturnType(){
   21.10 -
   21.11 -        String rttype = (new TypeSignature(getInternalSig())).getReturnType();
   21.12 -        return rttype;
   21.13 -    }
   21.14 -
   21.15 -    /**
   21.16 -     * Return java type parameter signature.
   21.17 -     */
   21.18 -    public String getParameters(){
   21.19 -        String ptype = (new TypeSignature(getInternalSig())).getParameters();
   21.20 -
   21.21 -        return ptype;
   21.22 -    }
   21.23 -
   21.24 -    /**
   21.25       * Return code attribute data of a method.
   21.26       */
   21.27      public byte[] getCode(){
   21.28 @@ -336,13 +318,6 @@
   21.29      }
   21.30  
   21.31      /**
   21.32 -     * Return number of arguments of that method.
   21.33 -     */
   21.34 -    public int getArgumentlength(){
   21.35 -        return new TypeSignature(getInternalSig()).getArgumentlength();
   21.36 -    }
   21.37 -
   21.38 -    /**
   21.39       * Return true if method is static
   21.40       */
   21.41      public boolean isStatic(){
    22.1 --- a/javap/src/main/java/org/apidesign/javap/TypeSignature.java	Wed Dec 12 12:37:41 2012 +0100
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,295 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
    22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 - *
    22.8 - * This code is free software; you can redistribute it and/or modify it
    22.9 - * under the terms of the GNU General Public License version 2 only, as
   22.10 - * published by the Free Software Foundation.  Oracle designates this
   22.11 - * particular file as subject to the "Classpath" exception as provided
   22.12 - * by Oracle in the LICENSE file that accompanied this code.
   22.13 - *
   22.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   22.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.17 - * version 2 for more details (a copy is included in the LICENSE file that
   22.18 - * accompanied this code).
   22.19 - *
   22.20 - * You should have received a copy of the GNU General Public License version
   22.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   22.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.23 - *
   22.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.25 - * or visit www.oracle.com if you need additional information or have any
   22.26 - * questions.
   22.27 - */
   22.28 -
   22.29 -
   22.30 -package org.apidesign.javap;
   22.31 -
   22.32 -import java.util.*;
   22.33 -import java.io.*;
   22.34 -
   22.35 -/**
   22.36 - * Returns java type signature.
   22.37 - *
   22.38 - * @author  Sucheta Dambalkar
   22.39 - */
   22.40 -public class TypeSignature {
   22.41 -
   22.42 -    String parameters = null;
   22.43 -    String returntype = null;
   22.44 -    String fieldtype = null;
   22.45 -    int argumentlength = 0;
   22.46 -
   22.47 -    public TypeSignature(String JVMSignature){
   22.48 -
   22.49 -        if(JVMSignature != null){
   22.50 -            if(JVMSignature.indexOf("(") == -1){
   22.51 -                //This is a field type.
   22.52 -                this.fieldtype = getFieldTypeSignature(JVMSignature);
   22.53 -            }else {
   22.54 -                String parameterdes = null;
   22.55 -                if((JVMSignature.indexOf(")")-1) > (JVMSignature.indexOf("("))){
   22.56 -                    //Get parameter signature.
   22.57 -                    parameterdes =
   22.58 -                        JVMSignature.substring(JVMSignature.indexOf("(")+1,
   22.59 -                                               JVMSignature.indexOf(")"));
   22.60 -                    this.parameters = getParametersHelper(parameterdes);
   22.61 -                }else this.parameters = "()";
   22.62 -                //Get return type signature.
   22.63 -                String returndes = JVMSignature.substring(JVMSignature.lastIndexOf(")")+1);
   22.64 -                this.returntype = getReturnTypeHelper(returndes);
   22.65 -            }
   22.66 -        }
   22.67 -    }
   22.68 -
   22.69 -    /**
   22.70 -     * Returns java type signature of a field.
   22.71 -     */
   22.72 -    public String getFieldTypeSignature(String fielddes){
   22.73 -        if(fielddes.startsWith("L")){
   22.74 -            return(getObjectType(fielddes));
   22.75 -        }else if(fielddes.startsWith("[")){
   22.76 -            return(getArrayType(fielddes));
   22.77 -        }else
   22.78 -            return(getBaseType(fielddes));
   22.79 -    }
   22.80 -
   22.81 -    /**
   22.82 -     * Returns java type signature of a parameter.
   22.83 -     */
   22.84 -    public String getParametersHelper(String parameterdes){
   22.85 -        Vector parameters = new Vector();
   22.86 -        int startindex = -1;
   22.87 -        int endindex = -1;
   22.88 -        String param = "";
   22.89 -
   22.90 -        while(parameterdes != null){
   22.91 -
   22.92 -            if(parameterdes.startsWith("L")){
   22.93 -                //parameter is a object.
   22.94 -                startindex = parameterdes.indexOf("L");
   22.95 -                endindex = parameterdes.indexOf(";");
   22.96 -                if(startindex < parameterdes.length()) {
   22.97 -                    if(endindex == parameterdes.length()-1) {
   22.98 -                        //last parameter
   22.99 -                        param = parameterdes.substring(startindex);
  22.100 -                        parameterdes = null;
  22.101 -                    }else if(endindex+1 < parameterdes.length()){
  22.102 -                        //rest parameters
  22.103 -                        param = parameterdes.substring(startindex, endindex+1);
  22.104 -                        parameterdes = parameterdes.substring(endindex+1);
  22.105 -
  22.106 -                    }
  22.107 -                    parameters.add(getObjectType(param));
  22.108 -                }
  22.109 -            }else if(parameterdes.startsWith("[")){
  22.110 -                //parameter is an array.
  22.111 -                String componentType = "";
  22.112 -                int enddim = -1;
  22.113 -                int st = 0;
  22.114 -                while(true){
  22.115 -                    if(st < parameterdes.length()){
  22.116 -                        if(parameterdes.charAt(st) == '['){
  22.117 -
  22.118 -                            enddim = st;
  22.119 -                            st++;
  22.120 -                        }
  22.121 -                        else break;
  22.122 -                    }
  22.123 -                    else break;
  22.124 -                }
  22.125 -
  22.126 -                if(enddim+1 < parameterdes.length()){
  22.127 -                    /* Array dimension.*/
  22.128 -                    param = parameterdes.substring(0,enddim+1);
  22.129 -
  22.130 -                }
  22.131 -
  22.132 -                int stotherparam = param.lastIndexOf("[")+1;
  22.133 -
  22.134 -                if(stotherparam < parameterdes.length()){
  22.135 -                    componentType =  parameterdes.substring(stotherparam);
  22.136 -                }
  22.137 -
  22.138 -                if(componentType.startsWith("L")){
  22.139 -                    //parameter is array of objects.
  22.140 -                    startindex = parameterdes.indexOf("L");
  22.141 -                    endindex = parameterdes.indexOf(";");
  22.142 -
  22.143 -                    if(endindex ==  parameterdes.length()-1){
  22.144 -                        //last parameter
  22.145 -                        param += parameterdes.substring(startindex);
  22.146 -                        parameterdes = null;
  22.147 -                    }else if(endindex+1 <  parameterdes.length()){
  22.148 -                        //rest parameters
  22.149 -                        param += parameterdes.substring(startindex, endindex+1);
  22.150 -                        parameterdes = parameterdes.substring(endindex+1);
  22.151 -                    }
  22.152 -                }else{
  22.153 -                    //parameter is array of base type.
  22.154 -                    if(componentType.length() == 1){
  22.155 -                        //last parameter.
  22.156 -                        param += componentType;
  22.157 -                        parameterdes = null;
  22.158 -                    }
  22.159 -                    else if (componentType.length() > 1) {
  22.160 -                        //rest parameters.
  22.161 -                        param += componentType.substring(0,1);
  22.162 -                        parameterdes = componentType.substring(1);
  22.163 -                    }
  22.164 -                }
  22.165 -                parameters.add(getArrayType(param));
  22.166 -
  22.167 -
  22.168 -            }else {
  22.169 -
  22.170 -                //parameter is of base type.
  22.171 -                if(parameterdes.length() == 1){
  22.172 -                    //last parameter
  22.173 -                    param = parameterdes;
  22.174 -                    parameterdes = null;
  22.175 -                }
  22.176 -                else if (parameterdes.length() > 1) {
  22.177 -                    //rest parameters.
  22.178 -                    param = parameterdes.substring(0,1);
  22.179 -                    parameterdes = parameterdes.substring(1);
  22.180 -                }
  22.181 -                parameters.add(getBaseType(param));
  22.182 -            }
  22.183 -        }
  22.184 -
  22.185 -        /* number of arguments of a method.*/
  22.186 -        argumentlength =  parameters.size();
  22.187 -
  22.188 -        /* java type signature.*/
  22.189 -        String parametersignature = "(";
  22.190 -        int i;
  22.191 -
  22.192 -        for(i = 0; i < parameters.size(); i++){
  22.193 -            parametersignature += (String)parameters.elementAt(i);
  22.194 -            if(i != parameters.size()-1){
  22.195 -                parametersignature += ", ";
  22.196 -            }
  22.197 -        }
  22.198 -        parametersignature += ")";
  22.199 -        return parametersignature;
  22.200 -    }
  22.201 -
  22.202 -    /**
  22.203 -     * Returns java type signature for a return type.
  22.204 -     */
  22.205 -    public String getReturnTypeHelper(String returndes){
  22.206 -        return getFieldTypeSignature(returndes);
  22.207 -    }
  22.208 -
  22.209 -    /**
  22.210 -     * Returns java type signature for a base type.
  22.211 -     */
  22.212 -    public String getBaseType(String baseType){
  22.213 -        if(baseType != null){
  22.214 -            if(baseType.equals("B")) return "byte";
  22.215 -            else if(baseType.equals("C")) return "char";
  22.216 -            else if(baseType.equals("D")) return "double";
  22.217 -            else if(baseType.equals("F")) return "float";
  22.218 -            else if(baseType.equals("I")) return "int";
  22.219 -            else if(baseType.equals("J")) return "long";
  22.220 -            else if(baseType.equals("S")) return "short";
  22.221 -            else if(baseType.equals("Z")) return "boolean";
  22.222 -            else if(baseType.equals("V")) return "void";
  22.223 -        }
  22.224 -        return null;
  22.225 -    }
  22.226 -
  22.227 -    /**
  22.228 -     * Returns java type signature for a object type.
  22.229 -     */
  22.230 -    public String getObjectType(String JVMobjectType) {
  22.231 -        String objectType = "";
  22.232 -        int startindex = JVMobjectType.indexOf("L")+1;
  22.233 -        int endindex =  JVMobjectType.indexOf(";");
  22.234 -        if((startindex != -1) && (endindex != -1)){
  22.235 -            if((startindex < JVMobjectType.length()) && (endindex < JVMobjectType.length())){
  22.236 -                objectType = JVMobjectType.substring(startindex, endindex);
  22.237 -            }
  22.238 -            objectType = objectType.replace('/','.');
  22.239 -            return objectType;
  22.240 -        }
  22.241 -        return null;
  22.242 -    }
  22.243 -
  22.244 -    /**
  22.245 -     * Returns java type signature for array type.
  22.246 -     */
  22.247 -    public String getArrayType(String arrayType) {
  22.248 -        if(arrayType != null){
  22.249 -            String dimention = "";
  22.250 -
  22.251 -            while(arrayType.indexOf("[") != -1){
  22.252 -                dimention += "[]";
  22.253 -
  22.254 -                int startindex = arrayType.indexOf("[")+1;
  22.255 -                if(startindex <= arrayType.length()){
  22.256 -                arrayType = arrayType.substring(startindex);
  22.257 -                }
  22.258 -            }
  22.259 -
  22.260 -            String componentType = "";
  22.261 -            if(arrayType.startsWith("L")){
  22.262 -                componentType = getObjectType(arrayType);
  22.263 -            }else {
  22.264 -                componentType = getBaseType(arrayType);
  22.265 -            }
  22.266 -            return componentType+dimention;
  22.267 -        }
  22.268 -        return null;
  22.269 -    }
  22.270 -
  22.271 -    /**
  22.272 -     * Returns java type signature for parameters.
  22.273 -     */
  22.274 -     public String getParameters(){
  22.275 -        return parameters;
  22.276 -    }
  22.277 -
  22.278 -    /**
  22.279 -     * Returns java type signature for return type.
  22.280 -     */
  22.281 -    public String getReturnType(){
  22.282 -        return returntype;
  22.283 -    }
  22.284 -
  22.285 -    /**
  22.286 -     * Returns java type signature for field type.
  22.287 -     */
  22.288 -    public String getFieldType(){
  22.289 -        return fieldtype;
  22.290 -    }
  22.291 -
  22.292 -    /**
  22.293 -     * Return number of arguments of a method.
  22.294 -     */
  22.295 -    public int getArgumentlength(){
  22.296 -        return argumentlength;
  22.297 -    }
  22.298 -}
    23.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java	Wed Dec 12 12:37:41 2012 +0100
    23.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java	Wed Dec 12 12:41:06 2012 +0100
    23.3 @@ -19,12 +19,12 @@
    23.4  
    23.5  import java.io.IOException;
    23.6  import java.io.InputStream;
    23.7 -import java.lang.reflect.Method;
    23.8  import java.util.Set;
    23.9  import javax.script.Invocable;
   23.10  import javax.script.ScriptEngine;
   23.11  import javax.script.ScriptEngineManager;
   23.12  import javax.script.ScriptException;
   23.13 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   23.14  import org.testng.annotations.Test;
   23.15  import static org.testng.Assert.*;
   23.16  
   23.17 @@ -125,15 +125,7 @@
   23.18          if (sb == null) {
   23.19              sb = new StringBuilder();
   23.20          }
   23.21 -        try {
   23.22 -            Method m;
   23.23 -            Class<?> genJS = Class.forName("org.apidesign.vm4brwsr.GenJS");
   23.24 -            m = genJS.getDeclaredMethod("compile", Appendable.class, String[].class);
   23.25 -            m.setAccessible(true);
   23.26 -            m.invoke(null, sb, names);
   23.27 -        } catch (Exception exception) {
   23.28 -            throw new IOException(exception);
   23.29 -        }
   23.30 +        Bck2Brwsr.generate(sb, ProcessPageTest.class.getClassLoader(), names);
   23.31          ScriptEngineManager sem = new ScriptEngineManager();
   23.32          ScriptEngine js = sem.getEngineByExtension("js");
   23.33          try {
    24.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Dec 12 12:37:41 2012 +0100
    24.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Wed Dec 12 12:41:06 2012 +0100
    24.3 @@ -70,6 +70,10 @@
    24.4      private static void setValue(double v) {
    24.5          StringBuilder sb = new StringBuilder();
    24.6          sb.append(v);
    24.7 +        if (sb.toString().endsWith(".0")) {
    24.8 +            final int l = sb.length();
    24.9 +            sb.delete(l - 2, l);
   24.10 +        }
   24.11          Calculator.DISPLAY.setValue(sb.toString());
   24.12      }
   24.13  
    25.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Bck2BrswrMojo.java	Wed Dec 12 12:37:41 2012 +0100
    25.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Bck2BrswrMojo.java	Wed Dec 12 12:41:06 2012 +0100
    25.3 @@ -21,7 +21,7 @@
    25.4  
    25.5  import java.io.File;
    25.6  import java.io.FileWriter;
    25.7 -import java.lang.reflect.Method;
    25.8 +import java.io.IOException;
    25.9  import java.net.MalformedURLException;
   25.10  import java.net.URL;
   25.11  import java.net.URLClassLoader;
   25.12 @@ -34,6 +34,7 @@
   25.13  import org.apache.maven.plugins.annotations.Mojo;
   25.14  import org.apache.maven.plugins.annotations.Parameter;
   25.15  import org.apache.maven.project.MavenProject;
   25.16 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   25.17  
   25.18  /** Compiles classes into JavaScript. */
   25.19  @Mojo(name="j2js", defaultPhase=LifecyclePhase.PROCESS_CLASSES)
   25.20 @@ -72,14 +73,10 @@
   25.21  
   25.22          try {
   25.23              URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
   25.24 -            
   25.25 -            Class<?> c = Class.forName("org.apidesign.vm4brwsr.GenJS");
   25.26 -            Method m = c.getDeclaredMethod("compile", ClassLoader.class, Appendable.class, String[].class);
   25.27 -            m.setAccessible(true);
   25.28              FileWriter w = new FileWriter(javascript);
   25.29 -            m.invoke(null, url, w, arr.toArray(new String[0]));
   25.30 +            Bck2Brwsr.generate(w, url, arr.toArray(new String[0]));
   25.31              w.close();
   25.32 -        } catch (Exception ex) {
   25.33 +        } catch (IOException ex) {
   25.34              throw new MojoExecutionException("Can't compile", ex);
   25.35          }
   25.36      }
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Wed Dec 12 12:41:06 2012 +0100
    26.3 @@ -0,0 +1,106 @@
    26.4 +/**
    26.5 + * Back 2 Browser Bytecode Translator
    26.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    26.7 + *
    26.8 + * This program is free software: you can redistribute it and/or modify
    26.9 + * it under the terms of the GNU General Public License as published by
   26.10 + * the Free Software Foundation, version 2 of the License.
   26.11 + *
   26.12 + * This program is distributed in the hope that it will be useful,
   26.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.15 + * GNU General Public License for more details.
   26.16 + *
   26.17 + * You should have received a copy of the GNU General Public License
   26.18 + * along with this program. Look for COPYING file in the top folder.
   26.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   26.20 + */
   26.21 +package org.apidesign.vm4brwsr;
   26.22 +
   26.23 +import java.io.IOException;
   26.24 +import java.io.InputStream;
   26.25 +import java.net.URL;
   26.26 +import java.util.Enumeration;
   26.27 +
   26.28 +/** Build your own virtual machine! Use methods in this class to generate
   26.29 + * a skeleton JVM in JavaScript that contains pre-compiled classes of your
   26.30 + * choice. The generated script defines one JavaScript method that can
   26.31 + * be used to bootstrap and load the virtual machine: <pre>
   26.32 + * var vm = bck2brwsr();
   26.33 + * var main = vm.loadClass('org.your.pkg.Main');
   26.34 + * main.main__V_3Ljava_lang_String_2(null);
   26.35 + * </pre>
   26.36 + * In case one wants to initialize the virtual machine with ability to
   26.37 + * load classes lazily when needed, one can provide a loader function to
   26.38 + * when creating the virtual machine: <pre>
   26.39 + * var vm = bck2brwsr(function(resource) { 
   26.40 + *   return null; // byte[] for the resource
   26.41 + * });
   26.42 + * </pre>
   26.43 + * In this scenario, when a request for a unknown class is made, the loader
   26.44 + * function is asked for its byte code and the system dynamically transforms
   26.45 + * it to JavaScript.
   26.46 + *
   26.47 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   26.48 + */
   26.49 +public final class Bck2Brwsr {
   26.50 +    private Bck2Brwsr() {
   26.51 +    }
   26.52 +    
   26.53 +    /** Generates virtual machine from bytes served by a <code>resources</code>
   26.54 +     * provider.
   26.55 +     * 
   26.56 +     * @param out the output to write the generated JavaScript to
   26.57 +     * @param resources provider of class files to use
   26.58 +     * @param classes additional classes to include in the generated script
   26.59 +     * @throws IOException I/O exception can be thrown when something goes wrong
   26.60 +     */
   26.61 +    public static void generate(Appendable out, Resources resources, String... classes) throws IOException {
   26.62 +        StringArray arr = StringArray.asList(classes);
   26.63 +        arr.add(VM.class.getName().replace('.', '/'));
   26.64 +        VM.compile(resources, out, arr);
   26.65 +    }
   26.66 +    
   26.67 +    /** Generates virtual machine from bytes served by a class loader.
   26.68 +     * 
   26.69 +     * @param out the output to write the generated JavaScript to
   26.70 +     * @param loader class loader to load needed classes from
   26.71 +     * @param classes additional classes to include in the generated script
   26.72 +     * @throws IOException I/O exception can be thrown when something goes wrong
   26.73 +     */
   26.74 +    public static void generate(Appendable out, final ClassLoader loader, String... classes) throws IOException {
   26.75 +        class R implements Resources {
   26.76 +            @Override
   26.77 +            public InputStream get(String name) throws IOException {
   26.78 +                Enumeration<URL> en = loader.getResources(name);
   26.79 +                URL u = null;
   26.80 +                while (en.hasMoreElements()) {
   26.81 +                    u = en.nextElement();
   26.82 +                }
   26.83 +                if (u == null) {
   26.84 +                    throw new IOException("Can't find " + name);
   26.85 +                }
   26.86 +                return u.openStream();
   26.87 +            }
   26.88 +        }
   26.89 +        generate(out, new R(), classes);
   26.90 +    }
   26.91 +    
   26.92 +    /** Provider of resources (classes and other files). The 
   26.93 +     * {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[]) 
   26.94 +     * generator method} will call back here for all classes needed during
   26.95 +     * translation to JavaScript.
   26.96 +     */
   26.97 +    public interface Resources {
   26.98 +        /** Loads given resource (class or other file like image). The 
   26.99 +         * resource name to load bytes for the {@link String} class
  26.100 +         * would be <code>"java/lang/String.class"</code>.
  26.101 +         * 
  26.102 +         * @param resource path to resource to load
  26.103 +         * @return the input stream for the resource 
  26.104 +         * @throws IOException can be thrown if the loading fails on some error
  26.105 +         *   or the file cannot be found
  26.106 +         */
  26.107 +        public InputStream get(String resource) throws IOException;
  26.108 +    }
  26.109 +}
    27.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Dec 12 12:37:41 2012 +0100
    27.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Dec 12 12:41:06 2012 +0100
    27.3 @@ -19,6 +19,7 @@
    27.4  
    27.5  import java.io.IOException;
    27.6  import java.io.InputStream;
    27.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    27.8  import org.apidesign.javap.AnnotationParser;
    27.9  import org.apidesign.javap.ClassData;
   27.10  import org.apidesign.javap.FieldData;
   27.11 @@ -29,9 +30,9 @@
   27.12   *
   27.13   * @author Jaroslav Tulach <jtulach@netbeans.org>
   27.14   */
   27.15 -public abstract class ByteCodeToJavaScript {
   27.16 +abstract class ByteCodeToJavaScript {
   27.17      private ClassData jc;
   27.18 -    private final Appendable out;
   27.19 +    final Appendable out;
   27.20  
   27.21      protected ByteCodeToJavaScript(Appendable out) {
   27.22          this.out = out;
   27.23 @@ -56,9 +57,12 @@
   27.24       * 
   27.25       * @param className suggested name of the class
   27.26       */
   27.27 -    protected String assignClass(String className) {
   27.28 +    /* protected */ String assignClass(String className) {
   27.29          return className + " = ";
   27.30      }
   27.31 +    /* protected */ String accessClass(String classOperation) {
   27.32 +        return classOperation;
   27.33 +    }
   27.34  
   27.35      /**
   27.36       * Converts a given class file to a JavaScript version.
   27.37 @@ -98,12 +102,15 @@
   27.38          }
   27.39          if (proto == null) {
   27.40              String sc = jc.getSuperClassName(); // with _
   27.41 -            out.append("\n    var p = CLS.prototype = ").
   27.42 -                append(sc.replace('/', '_')).append("(true);");
   27.43 +            out.append("\n    var pp = ").
   27.44 +                append(accessClass(sc.replace('/', '_'))).append("(true);");
   27.45 +            out.append("\n    var p = CLS.prototype = pp;");
   27.46              out.append("\n    var c = p;");
   27.47 +            out.append("\n    var sprcls = pp.constructor.$class;");
   27.48          } else {
   27.49              out.append("\n    var p = CLS.prototype = ").append(proto[1]).append(";");
   27.50              out.append("\n    var c = ").append(proto[0]).append(";");
   27.51 +            out.append("\n    var sprcls = null;");
   27.52          }
   27.53          for (MethodData m : jc.getMethods()) {
   27.54              byte[] onlyArr = m.findAnnotationData(true);
   27.55 @@ -118,10 +125,17 @@
   27.56                  }
   27.57                  continue;
   27.58              }
   27.59 +            String mn;
   27.60              if (m.isStatic()) {
   27.61 -                generateStaticMethod("\n    c.", m, toInitilize);
   27.62 +                mn = generateStaticMethod("\n    c.", m, toInitilize);
   27.63              } else {
   27.64 -                generateInstanceMethod("\n    c.", m);
   27.65 +                mn = generateInstanceMethod("\n    c.", m);
   27.66 +            }
   27.67 +            byte[] runAnno = m.findAnnotationData(false);
   27.68 +            if (runAnno != null) {
   27.69 +                out.append("\n    c.").append(mn).append(".anno = {");
   27.70 +                generateAnno(jc, out, runAnno);
   27.71 +                out.append("\n    };");
   27.72              }
   27.73          }
   27.74          out.append("\n    c.constructor = CLS;");
   27.75 @@ -129,6 +143,17 @@
   27.76          for (String superInterface : jc.getSuperInterfaces()) {
   27.77              out.append("\n    c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
   27.78          }
   27.79 +        out.append("\n    CLS.$class = ");
   27.80 +        out.append(accessClass("java_lang_Class(true);"));
   27.81 +        out.append("\n    CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
   27.82 +        out.append("\n    CLS.$class.superclass = sprcls;");
   27.83 +        out.append("\n    CLS.$class.cnstr = CLS;");
   27.84 +        byte[] classAnno = jc.findAnnotationData(false);
   27.85 +        if (classAnno != null) {
   27.86 +            out.append("\n    CLS.$class.anno = {");
   27.87 +            generateAnno(jc, out, classAnno);
   27.88 +            out.append("\n    };");
   27.89 +        }
   27.90          out.append("\n  }");
   27.91          out.append("\n  if (arguments.length === 0) {");
   27.92          out.append("\n    if (!(this instanceof CLS)) {");
   27.93 @@ -162,15 +187,16 @@
   27.94          }
   27.95          return sb.toString();
   27.96      }
   27.97 -    private void generateStaticMethod(String prefix, MethodData m, StringArray toInitilize) throws IOException {
   27.98 -        if (javaScriptBody(prefix, m, true)) {
   27.99 -            return;
  27.100 +    private String generateStaticMethod(String prefix, MethodData m, StringArray toInitilize) throws IOException {
  27.101 +        String jsb = javaScriptBody(prefix, m, true);
  27.102 +        if (jsb != null) {
  27.103 +            return jsb;
  27.104          }
  27.105          StringBuilder argsCnt = new StringBuilder();
  27.106          final String mn = findMethodName(m, argsCnt);
  27.107          out.append(prefix).append(mn).append(" = function");
  27.108          if (mn.equals("class__V")) {
  27.109 -            toInitilize.add(className(jc) + "(false)." + mn);
  27.110 +            toInitilize.add(accessClass(className(jc)) + "(false)." + mn);
  27.111          }
  27.112          out.append('(');
  27.113          String space = "";
  27.114 @@ -199,11 +225,13 @@
  27.115              out.append("  throw 'no code found for ").append(m.getInternalSig()).append("';\n");
  27.116          }
  27.117          out.append("};");
  27.118 +        return mn;
  27.119      }
  27.120      
  27.121 -    private void generateInstanceMethod(String prefix, MethodData m) throws IOException {
  27.122 -        if (javaScriptBody(prefix, m, false)) {
  27.123 -            return;
  27.124 +    private String generateInstanceMethod(String prefix, MethodData m) throws IOException {
  27.125 +        String jsb = javaScriptBody(prefix, m, false);
  27.126 +        if (jsb != null) {
  27.127 +            return jsb;
  27.128          }
  27.129          StringBuilder argsCnt = new StringBuilder();
  27.130          final String mn = findMethodName(m, argsCnt);
  27.131 @@ -233,6 +261,7 @@
  27.132              out.append("  throw 'no code found for ").append(m.getInternalSig()).append("';\n");
  27.133          }
  27.134          out.append("};");
  27.135 +        return mn;
  27.136      }
  27.137  
  27.138      private void produceCode(byte[] byteCodes) throws IOException {
  27.139 @@ -614,7 +643,7 @@
  27.140                      int indx = readIntArg(byteCodes, i);
  27.141                      String ci = jc.getClassName(indx);
  27.142                      out.append("s.push(new ");
  27.143 -                    out.append(ci.replace('/','_'));
  27.144 +                    out.append(accessClass(ci.replace('/','_')));
  27.145                      out.append("());");
  27.146                      addReference(ci);
  27.147                      i += 2;
  27.148 @@ -707,7 +736,7 @@
  27.149                  case opc_getstatic: {
  27.150                      int indx = readIntArg(byteCodes, i);
  27.151                      String[] fi = jc.getFieldInfoName(indx);
  27.152 -                    out.append("s.push(").append(fi[0].replace('/', '_'));
  27.153 +                    out.append("s.push(").append(accessClass(fi[0].replace('/', '_')));
  27.154                      out.append('.').append(fi[1]).append(");");
  27.155                      i += 2;
  27.156                      addReference(fi[0]);
  27.157 @@ -716,7 +745,7 @@
  27.158                  case opc_putstatic: {
  27.159                      int indx = readIntArg(byteCodes, i);
  27.160                      String[] fi = jc.getFieldInfoName(indx);
  27.161 -                    out.append(fi[0].replace('/', '_'));
  27.162 +                    out.append(accessClass(fi[0].replace('/', '_')));
  27.163                      out.append('.').append(fi[1]).append(" = s.pop();");
  27.164                      i += 2;
  27.165                      addReference(fi[0]);
  27.166 @@ -735,9 +764,9 @@
  27.167                      final String type = jc.getClassName(indx);
  27.168                      if (!type.startsWith("[")) {
  27.169                          // no way to check arrays right now
  27.170 -                        out.append("if(s[s.length - 1].$instOf_")
  27.171 +                        out.append("if(s[s.length - 1] !== null && !s[s.length - 1].$instOf_")
  27.172                             .append(type.replace('/', '_'))
  27.173 -                           .append(" != 1) throw {};"); // XXX proper exception
  27.174 +                           .append(") throw {};"); // XXX proper exception
  27.175                      }
  27.176                      i += 2;
  27.177                      break;
  27.178 @@ -927,7 +956,7 @@
  27.179              out.append("s.push(");
  27.180          }
  27.181          final String in = mi[0];
  27.182 -        out.append(in.replace('/', '_'));
  27.183 +        out.append(accessClass(in.replace('/', '_')));
  27.184          out.append("(false).");
  27.185          out.append(mn);
  27.186          out.append('(');
  27.187 @@ -1002,24 +1031,33 @@
  27.188          }
  27.189      }
  27.190  
  27.191 -    private String encodeConstant(int entryIndex) {
  27.192 -        String s = jc.stringValue(entryIndex, true);
  27.193 +    private String encodeConstant(int entryIndex) throws IOException {
  27.194 +        String[] classRef = { null };
  27.195 +        String s = jc.stringValue(entryIndex, classRef);
  27.196 +        if (classRef[0] != null) {
  27.197 +            addReference(classRef[0]);
  27.198 +            s = accessClass(s.replace('/', '_')) + "(false).constructor.$class";
  27.199 +        }
  27.200          return s;
  27.201      }
  27.202  
  27.203 -    private boolean javaScriptBody(String prefix, MethodData m, boolean isStatic) throws IOException {
  27.204 +    private String javaScriptBody(String prefix, MethodData m, boolean isStatic) throws IOException {
  27.205          byte[] arr = m.findAnnotationData(true);
  27.206          if (arr == null) {
  27.207 -            return false;
  27.208 +            return null;
  27.209          }
  27.210          final String jvmType = "Lorg/apidesign/bck2brwsr/core/JavaScriptBody;";
  27.211          class P extends AnnotationParser {
  27.212 +            public P() {
  27.213 +                super(false);
  27.214 +            }
  27.215 +            
  27.216              int cnt;
  27.217              String[] args = new String[30];
  27.218              String body;
  27.219              
  27.220              @Override
  27.221 -            protected void visitAttr(String type, String attr, String value) {
  27.222 +            protected void visitAttr(String type, String attr, String at, String value) {
  27.223                  if (type.equals(jvmType)) {
  27.224                      if ("body".equals(attr)) {
  27.225                          body = value;
  27.226 @@ -1034,10 +1072,11 @@
  27.227          P p = new P();
  27.228          p.parse(arr, jc);
  27.229          if (p.body == null) {
  27.230 -            return false;
  27.231 +            return null;
  27.232          }
  27.233          StringBuilder cnt = new StringBuilder();
  27.234 -        out.append(prefix).append(findMethodName(m, cnt));
  27.235 +        final String mn = findMethodName(m, cnt);
  27.236 +        out.append(prefix).append(mn);
  27.237          out.append(" = function(");
  27.238          String space;
  27.239          int index;
  27.240 @@ -1058,7 +1097,7 @@
  27.241          out.append(") {").append("\n");
  27.242          out.append(p.body);
  27.243          out.append("\n}\n");
  27.244 -        return true;
  27.245 +        return mn;
  27.246      }
  27.247      private static String className(ClassData jc) {
  27.248          //return jc.getName().getInternalName().replace('/', '_');
  27.249 @@ -1075,9 +1114,9 @@
  27.250          final String[] values = new String[attrNames.length];
  27.251          final boolean[] found = { false };
  27.252          final String jvmType = "L" + className.replace('.', '/') + ";";
  27.253 -        AnnotationParser ap = new AnnotationParser() {
  27.254 +        AnnotationParser ap = new AnnotationParser(false) {
  27.255              @Override
  27.256 -            protected void visitAttr(String type, String attr, String value) {
  27.257 +            protected void visitAttr(String type, String attr, String at, String value) {
  27.258                  if (type.equals(jvmType)) {
  27.259                      found[0] = true;
  27.260                      for (int i = 0; i < attrNames.length; i++) {
  27.261 @@ -1111,4 +1150,38 @@
  27.262          }
  27.263          return " = null;";
  27.264      }
  27.265 +
  27.266 +    private static void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
  27.267 +        AnnotationParser ap = new AnnotationParser(true) {
  27.268 +            int anno;
  27.269 +            int cnt;
  27.270 +            
  27.271 +            @Override
  27.272 +            protected void visitAnnotationStart(String type) throws IOException {
  27.273 +                if (anno++ > 0) {
  27.274 +                    out.append(",");
  27.275 +                }
  27.276 +                out.append('"').append(type).append("\" : {\n");
  27.277 +                cnt = 0;
  27.278 +            }
  27.279 +
  27.280 +            @Override
  27.281 +            protected void visitAnnotationEnd(String type) throws IOException {
  27.282 +                out.append("\n}\n");
  27.283 +            }
  27.284 +            
  27.285 +            @Override
  27.286 +            protected void visitAttr(String type, String attr, String attrType, String value) 
  27.287 +            throws IOException {
  27.288 +                if (attr == null) {
  27.289 +                    return;
  27.290 +                }
  27.291 +                if (cnt++ > 0) {
  27.292 +                    out.append(",\n");
  27.293 +                }
  27.294 +                out.append(attr).append("__").append(attrType).append(" : ").append(value);
  27.295 +            }
  27.296 +        };
  27.297 +        ap.parse(data, cd);
  27.298 +    }
  27.299  }
    28.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/GenJS.java	Wed Dec 12 12:37:41 2012 +0100
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,203 +0,0 @@
    28.4 -/**
    28.5 - * Back 2 Browser Bytecode Translator
    28.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    28.7 - *
    28.8 - * This program is free software: you can redistribute it and/or modify
    28.9 - * it under the terms of the GNU General Public License as published by
   28.10 - * the Free Software Foundation, version 2 of the License.
   28.11 - *
   28.12 - * This program is distributed in the hope that it will be useful,
   28.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.15 - * GNU General Public License for more details.
   28.16 - *
   28.17 - * You should have received a copy of the GNU General Public License
   28.18 - * along with this program. Look for COPYING file in the top folder.
   28.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   28.20 - */
   28.21 -package org.apidesign.vm4brwsr;
   28.22 -
   28.23 -import java.io.IOException;
   28.24 -import java.io.InputStream;
   28.25 -import java.net.URL;
   28.26 -import java.util.Enumeration;
   28.27 -
   28.28 -/** Generator of JavaScript from bytecode of classes on classpath of the VM.
   28.29 - *
   28.30 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   28.31 - */
   28.32 -final class GenJS extends ByteCodeToJavaScript {
   28.33 -    public GenJS(Appendable out) {
   28.34 -        super(out);
   28.35 -    }
   28.36 -    
   28.37 -    static void compile(Appendable out, String... names) throws IOException {
   28.38 -        compile(out, StringArray.asList(names));
   28.39 -    }
   28.40 -    static void compile(ClassLoader l, Appendable out, String... names) throws IOException {
   28.41 -        compile(l, out, StringArray.asList(names));
   28.42 -    }
   28.43 -    static void compile(Appendable out, StringArray names) throws IOException {
   28.44 -        compile(GenJS.class.getClassLoader(), out, names);
   28.45 -    }
   28.46 -    static void compile(ClassLoader l, Appendable out, StringArray names) throws IOException {
   28.47 -        out.append("Array.prototype.fillNulls = function() {\n" +
   28.48 -             "  for(var i = 0; i < this.length; i++) {\n" +
   28.49 -             "    this[i] = null;\n" +
   28.50 -             "  }\n" +
   28.51 -             "  return this;\n" +
   28.52 -             "};");
   28.53 -        
   28.54 -        
   28.55 -        StringArray processed = new StringArray();
   28.56 -        StringArray initCode = new StringArray();
   28.57 -        for (String baseClass : names.toArray()) {
   28.58 -            GenJS js = new GenJS(out);
   28.59 -            js.references.add(baseClass);
   28.60 -            for (;;) {
   28.61 -                String name = null;
   28.62 -                for (String n : js.references.toArray()) {
   28.63 -                    if (processed.contains(n)) {
   28.64 -                        continue;
   28.65 -                    }
   28.66 -                    name = n;
   28.67 -                }
   28.68 -                if (name == null) {
   28.69 -                    break;
   28.70 -                }
   28.71 -                InputStream is = loadClass(l, name);
   28.72 -                if (is == null) {
   28.73 -                    throw new IOException("Can't find class " + name); 
   28.74 -                }
   28.75 -                try {
   28.76 -                    String ic = js.compile(is);
   28.77 -                    processed.add(name);
   28.78 -                    initCode.add(ic == null ? "" : ic);
   28.79 -                } catch (RuntimeException ex) {
   28.80 -                    if (out instanceof CharSequence) {
   28.81 -                        CharSequence seq = (CharSequence)out;
   28.82 -                        int lastBlock = seq.length();
   28.83 -                        while (lastBlock-- > 0) {
   28.84 -                            if (seq.charAt(lastBlock) == '{') {
   28.85 -                                break;
   28.86 -                            }
   28.87 -                        }
   28.88 -                        throw new IOException("Error while compiling " + name + "\n" 
   28.89 -                            + seq.subSequence(lastBlock + 1, seq.length()), ex
   28.90 -                        );
   28.91 -                    } else {
   28.92 -                        throw new IOException("Error while compiling " + name + "\n" 
   28.93 -                            + out, ex
   28.94 -                        );
   28.95 -                    }
   28.96 -                }
   28.97 -                for (String resource : js.scripts.toArray()) {
   28.98 -                    while (resource.startsWith("/")) {
   28.99 -                        resource = resource.substring(1);
  28.100 -                    }
  28.101 -                    InputStream emul = l.getResourceAsStream(resource);
  28.102 -                    if (emul == null) {
  28.103 -                        throw new IOException("Can't find " + resource);
  28.104 -                    }
  28.105 -                    readResource(emul, out);
  28.106 -                }
  28.107 -                js.scripts = new StringArray();
  28.108 -            }
  28.109 -
  28.110 -            StringArray toInit = StringArray.asList(js.references.toArray());
  28.111 -            toInit.reverse();
  28.112 -
  28.113 -            for (String ic : toInit.toArray()) {
  28.114 -                int indx = processed.indexOf(ic);
  28.115 -                if (indx >= 0) {
  28.116 -                    out.append(initCode.toArray()[indx]).append("\n");
  28.117 -                    initCode.toArray()[indx] = "";
  28.118 -                }
  28.119 -            }
  28.120 -
  28.121 -        }
  28.122 -    }
  28.123 -    private static void readResource(InputStream emul, Appendable out) throws IOException {
  28.124 -        try {
  28.125 -            int state = 0;
  28.126 -            for (;;) {
  28.127 -                int ch = emul.read();
  28.128 -                if (ch == -1) {
  28.129 -                    break;
  28.130 -                }
  28.131 -                if (ch < 0 || ch > 255) {
  28.132 -                    throw new IOException("Invalid char in emulation " + ch);
  28.133 -                }
  28.134 -                switch (state) {
  28.135 -                    case 0: 
  28.136 -                        if (ch == '/') {
  28.137 -                            state = 1;
  28.138 -                        } else {
  28.139 -                            out.append((char)ch);
  28.140 -                        }
  28.141 -                        break;
  28.142 -                    case 1:
  28.143 -                        if (ch == '*') {
  28.144 -                            state = 2;
  28.145 -                        } else {
  28.146 -                            out.append('/').append((char)ch);
  28.147 -                            state = 0;
  28.148 -                        }
  28.149 -                        break;
  28.150 -                    case 2:
  28.151 -                        if (ch == '*') {
  28.152 -                            state = 3;
  28.153 -                        }
  28.154 -                        break;
  28.155 -                    case 3:
  28.156 -                        if (ch == '/') {
  28.157 -                            state = 0;
  28.158 -                        } else {
  28.159 -                            state = 2;
  28.160 -                        }
  28.161 -                        break;
  28.162 -                }
  28.163 -            }
  28.164 -        } finally {
  28.165 -            emul.close();
  28.166 -        }
  28.167 -    }
  28.168 -
  28.169 -    private static InputStream loadClass(ClassLoader l, String name) throws IOException {
  28.170 -        Enumeration<URL> en = l.getResources(name + ".class");
  28.171 -        URL u = null;
  28.172 -        while (en.hasMoreElements()) {
  28.173 -            u = en.nextElement();
  28.174 -        }
  28.175 -        if (u == null) {
  28.176 -            throw new IOException("Can't find " + name);
  28.177 -        }
  28.178 -        if (u.toExternalForm().contains("rt.jar!")) {
  28.179 -            throw new IOException("No emulation for " + u);
  28.180 -        }
  28.181 -        return u.openStream();
  28.182 -    }
  28.183 -
  28.184 -    static String toString(String name) throws IOException {
  28.185 -        StringBuilder sb = new StringBuilder();
  28.186 -        compile(sb, name);
  28.187 -        return sb.toString().toString();
  28.188 -    }
  28.189 -
  28.190 -    private StringArray scripts = new StringArray();
  28.191 -    private StringArray references = new StringArray();
  28.192 -    
  28.193 -    @Override
  28.194 -    protected boolean requireReference(String cn) {
  28.195 -        if (references.contains(cn)) {
  28.196 -            return false;
  28.197 -        }
  28.198 -        references.add(cn);
  28.199 -        return true;
  28.200 -    }
  28.201 -
  28.202 -    @Override
  28.203 -    protected void requireScript(String resourcePath) {
  28.204 -        scripts.add(resourcePath);
  28.205 -    }
  28.206 -}
    29.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Wed Dec 12 12:37:41 2012 +0100
    29.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Wed Dec 12 12:41:06 2012 +0100
    29.3 @@ -32,6 +32,7 @@
    29.4      
    29.5      public static void main(String... args) throws IOException {
    29.6          if (args.length < 2) {
    29.7 +            System.err.println("Bck2Brwsr Translator from Java(tm) to JavaScript, (c) Jaroslav Tulach 2012");
    29.8              System.err.println("Usage: java -cp ... -jar ... <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
    29.9              return;
   29.10          }
   29.11 @@ -39,7 +40,7 @@
   29.12          Writer w = new BufferedWriter(new FileWriter(args[0]));
   29.13          StringArray classes = StringArray.asList(args);
   29.14          classes.delete(0);
   29.15 -        GenJS.compile(w, classes);
   29.16 +        Bck2Brwsr.generate(w, Main.class.getClassLoader(), classes.toArray());
   29.17          w.close();
   29.18      }
   29.19  }
    30.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Wed Dec 12 12:37:41 2012 +0100
    30.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Wed Dec 12 12:41:06 2012 +0100
    30.3 @@ -48,7 +48,7 @@
    30.4          return arr == null ? new String[0] : arr;
    30.5      }
    30.6      
    30.7 -    static StringArray asList(String[] names) {
    30.8 +    static StringArray asList(String... names) {
    30.9          return new StringArray(names);
   30.10      }
   30.11  
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed Dec 12 12:41:06 2012 +0100
    31.3 @@ -0,0 +1,208 @@
    31.4 +/**
    31.5 + * Back 2 Browser Bytecode Translator
    31.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    31.7 + *
    31.8 + * This program is free software: you can redistribute it and/or modify
    31.9 + * it under the terms of the GNU General Public License as published by
   31.10 + * the Free Software Foundation, version 2 of the License.
   31.11 + *
   31.12 + * This program is distributed in the hope that it will be useful,
   31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.15 + * GNU General Public License for more details.
   31.16 + *
   31.17 + * You should have received a copy of the GNU General Public License
   31.18 + * along with this program. Look for COPYING file in the top folder.
   31.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   31.20 + */
   31.21 +package org.apidesign.vm4brwsr;
   31.22 +
   31.23 +import java.io.IOException;
   31.24 +import java.io.InputStream;
   31.25 +
   31.26 +/** Generator of JavaScript from bytecode of classes on classpath of the VM.
   31.27 + *
   31.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   31.29 + */
   31.30 +class VM extends ByteCodeToJavaScript {
   31.31 +    public VM(Appendable out) {
   31.32 +        super(out);
   31.33 +    }
   31.34 +    
   31.35 +    static {
   31.36 +        // uses VMLazy to load dynamic classes
   31.37 +        VMLazy.init();
   31.38 +    }
   31.39 +    
   31.40 +    static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
   31.41 +        new VM(out).doCompile(l, names);
   31.42 +    }
   31.43 +    protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
   31.44 +        out.append("(function VM(global) {");
   31.45 +        out.append("\n  var vm = {};");
   31.46 +        StringArray processed = new StringArray();
   31.47 +        StringArray initCode = new StringArray();
   31.48 +        for (String baseClass : names.toArray()) {
   31.49 +            references.add(baseClass);
   31.50 +            for (;;) {
   31.51 +                String name = null;
   31.52 +                for (String n : references.toArray()) {
   31.53 +                    if (processed.contains(n)) {
   31.54 +                        continue;
   31.55 +                    }
   31.56 +                    name = n;
   31.57 +                }
   31.58 +                if (name == null) {
   31.59 +                    break;
   31.60 +                }
   31.61 +                InputStream is = loadClass(l, name);
   31.62 +                if (is == null) {
   31.63 +                    throw new IOException("Can't find class " + name); 
   31.64 +                }
   31.65 +                try {
   31.66 +                    String ic = compile(is);
   31.67 +                    processed.add(name);
   31.68 +                    initCode.add(ic == null ? "" : ic);
   31.69 +                } catch (RuntimeException ex) {
   31.70 +                    if (out instanceof CharSequence) {
   31.71 +                        CharSequence seq = (CharSequence)out;
   31.72 +                        int lastBlock = seq.length();
   31.73 +                        while (lastBlock-- > 0) {
   31.74 +                            if (seq.charAt(lastBlock) == '{') {
   31.75 +                                break;
   31.76 +                            }
   31.77 +                        }
   31.78 +                        throw new IOException("Error while compiling " + name + "\n" 
   31.79 +                            + seq.subSequence(lastBlock + 1, seq.length()), ex
   31.80 +                        );
   31.81 +                    } else {
   31.82 +                        throw new IOException("Error while compiling " + name + "\n" 
   31.83 +                            + out, ex
   31.84 +                        );
   31.85 +                    }
   31.86 +                }
   31.87 +            }
   31.88 +
   31.89 +            for (String resource : scripts.toArray()) {
   31.90 +                while (resource.startsWith("/")) {
   31.91 +                    resource = resource.substring(1);
   31.92 +                }
   31.93 +                InputStream emul = l.get(resource);
   31.94 +                if (emul == null) {
   31.95 +                    throw new IOException("Can't find " + resource);
   31.96 +                }
   31.97 +                readResource(emul, out);
   31.98 +            }
   31.99 +            scripts = new StringArray();
  31.100 +            
  31.101 +            StringArray toInit = StringArray.asList(references.toArray());
  31.102 +            toInit.reverse();
  31.103 +
  31.104 +            for (String ic : toInit.toArray()) {
  31.105 +                int indx = processed.indexOf(ic);
  31.106 +                if (indx >= 0) {
  31.107 +                    out.append(initCode.toArray()[indx]).append("\n");
  31.108 +                    initCode.toArray()[indx] = "";
  31.109 +                }
  31.110 +            }
  31.111 +        }
  31.112 +        out.append(
  31.113 +              "  global.bck2brwsr = function() {\n"
  31.114 +            + "    var args = arguments;\n"
  31.115 +            + "    var loader = {};\n"
  31.116 +            + "    loader.vm = vm;\n"
  31.117 +            + "    loader.loadClass = function(name) {\n"
  31.118 +            + "      var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
  31.119 +            + "      var fn = vm[attr];\n"
  31.120 +            + "      if (fn) return fn(false);\n"
  31.121 +            + "      if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
  31.122 +            + "      return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
  31.123 +            + "        load___3Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
  31.124 +            + "    }\n"
  31.125 +            + "    return loader;\n"
  31.126 +            + "  };\n");
  31.127 +        out.append("}(this));");
  31.128 +    }
  31.129 +    private static void readResource(InputStream emul, Appendable out) throws IOException {
  31.130 +        try {
  31.131 +            int state = 0;
  31.132 +            for (;;) {
  31.133 +                int ch = emul.read();
  31.134 +                if (ch == -1) {
  31.135 +                    break;
  31.136 +                }
  31.137 +                if (ch < 0 || ch > 255) {
  31.138 +                    throw new IOException("Invalid char in emulation " + ch);
  31.139 +                }
  31.140 +                switch (state) {
  31.141 +                    case 0: 
  31.142 +                        if (ch == '/') {
  31.143 +                            state = 1;
  31.144 +                        } else {
  31.145 +                            out.append((char)ch);
  31.146 +                        }
  31.147 +                        break;
  31.148 +                    case 1:
  31.149 +                        if (ch == '*') {
  31.150 +                            state = 2;
  31.151 +                        } else {
  31.152 +                            out.append('/').append((char)ch);
  31.153 +                            state = 0;
  31.154 +                        }
  31.155 +                        break;
  31.156 +                    case 2:
  31.157 +                        if (ch == '*') {
  31.158 +                            state = 3;
  31.159 +                        }
  31.160 +                        break;
  31.161 +                    case 3:
  31.162 +                        if (ch == '/') {
  31.163 +                            state = 0;
  31.164 +                        } else {
  31.165 +                            state = 2;
  31.166 +                        }
  31.167 +                        break;
  31.168 +                }
  31.169 +            }
  31.170 +        } finally {
  31.171 +            emul.close();
  31.172 +        }
  31.173 +    }
  31.174 +
  31.175 +    private static InputStream loadClass(Bck2Brwsr.Resources l, String name) throws IOException {
  31.176 +        return l.get(name + ".class"); // NOI18N
  31.177 +    }
  31.178 +
  31.179 +    static String toString(String name) throws IOException {
  31.180 +        StringBuilder sb = new StringBuilder();
  31.181 +//        compile(sb, name);
  31.182 +        return sb.toString().toString();
  31.183 +    }
  31.184 +
  31.185 +    private StringArray scripts = new StringArray();
  31.186 +    private StringArray references = new StringArray();
  31.187 +    
  31.188 +    @Override
  31.189 +    protected boolean requireReference(String cn) {
  31.190 +        if (references.contains(cn)) {
  31.191 +            return false;
  31.192 +        }
  31.193 +        references.add(cn);
  31.194 +        return true;
  31.195 +    }
  31.196 +
  31.197 +    @Override
  31.198 +    protected void requireScript(String resourcePath) {
  31.199 +        scripts.add(resourcePath);
  31.200 +    }
  31.201 +
  31.202 +    @Override
  31.203 +    String assignClass(String className) {
  31.204 +        return "vm." + className + " = ";
  31.205 +    }
  31.206 +    
  31.207 +    @Override
  31.208 +    String accessClass(String className) {
  31.209 +        return "vm." + className;
  31.210 +    }
  31.211 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Wed Dec 12 12:41:06 2012 +0100
    32.3 @@ -0,0 +1,129 @@
    32.4 +/**
    32.5 + * Back 2 Browser Bytecode Translator
    32.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    32.7 + *
    32.8 + * This program is free software: you can redistribute it and/or modify
    32.9 + * it under the terms of the GNU General Public License as published by
   32.10 + * the Free Software Foundation, version 2 of the License.
   32.11 + *
   32.12 + * This program is distributed in the hope that it will be useful,
   32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.15 + * GNU General Public License for more details.
   32.16 + *
   32.17 + * You should have received a copy of the GNU General Public License
   32.18 + * along with this program. Look for COPYING file in the top folder.
   32.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   32.20 + */
   32.21 +package org.apidesign.vm4brwsr;
   32.22 +
   32.23 +import java.io.ByteArrayInputStream;
   32.24 +import java.io.IOException;
   32.25 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   32.26 +
   32.27 +/**
   32.28 + *
   32.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   32.30 + */
   32.31 +final class VMLazy {
   32.32 +    private final Object loader;
   32.33 +    private final Object[] args;
   32.34 +    
   32.35 +    private VMLazy(Object loader, Object[] args) {
   32.36 +        this.loader = loader;
   32.37 +        this.args = args;
   32.38 +    }
   32.39 +    
   32.40 +    static void init() {
   32.41 +    }
   32.42 +    
   32.43 +    @JavaScriptBody(args={"l", "res", "args" }, body = ""
   32.44 +        + "\ntry {"
   32.45 +        + "\n  return args[0](res.toString());"
   32.46 +        + "\n} catch (x) {"
   32.47 +        + "\n  throw Object.getOwnPropertyNames(l.vm).toString() + x.toString();"
   32.48 +        + "\n}")
   32.49 +    private static native byte[] read(Object l, String res, Object[] args);
   32.50 +    
   32.51 +    static Object load(Object loader, String name, Object[] arguments) 
   32.52 +    throws IOException, ClassNotFoundException {
   32.53 +        return new VMLazy(loader, arguments).load(name);
   32.54 +    }
   32.55 +    
   32.56 +    private Object load(String name)
   32.57 +    throws IOException, ClassNotFoundException {
   32.58 +        String res = name.replace('.', '/') + ".class";
   32.59 +        byte[] arr = read(loader, res, args);
   32.60 +        if (arr == null) {
   32.61 +            throw new ClassNotFoundException(name);
   32.62 +        }
   32.63 +//        beingDefined(loader, name);
   32.64 +        StringBuilder out = new StringBuilder();
   32.65 +        out.append("var loader = arguments[0];\n");
   32.66 +        out.append("var vm = loader.vm;\n");
   32.67 +        new Gen(this, out).compile(new ByteArrayInputStream(arr));
   32.68 +        String code = out.toString().toString();
   32.69 +        String under = name.replace('.', '_');
   32.70 +        return applyCode(loader, under, code);
   32.71 +    }
   32.72 +
   32.73 +/* possibly not needed:
   32.74 +    @JavaScriptBody(args = {"loader", "n" }, body =
   32.75 +        "var cls = n.replace__Ljava_lang_String_2CC(n, '.','_').toString();" +
   32.76 +        "loader.vm[cls] = true;\n"
   32.77 +    )
   32.78 +    private static native void beingDefined(Object loader, String name);
   32.79 +*/
   32.80 +    
   32.81 +
   32.82 +    @JavaScriptBody(args = {"loader", "name", "script" }, body =
   32.83 +        "try {\n" +
   32.84 +        "  new Function(script)(loader, name);\n" +
   32.85 +        "} catch (ex) {\n" +
   32.86 +        "  throw 'Cannot compile ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" +
   32.87 +        "}\n" +
   32.88 +        "return vm[name](false);\n"
   32.89 +    )
   32.90 +    private static native Object applyCode(Object loader, String name, String script);
   32.91 +    
   32.92 +    
   32.93 +    private static final class Gen extends ByteCodeToJavaScript {
   32.94 +        private final VMLazy lazy;
   32.95 +
   32.96 +        public Gen(VMLazy vm, Appendable out) {
   32.97 +            super(out);
   32.98 +            this.lazy = vm;
   32.99 +        }
  32.100 +        
  32.101 +        @JavaScriptBody(args = {"self", "n"},
  32.102 +        body =
  32.103 +        "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();"
  32.104 +        + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();"
  32.105 +        + "\nvar lazy = self.fld_lazy;"
  32.106 +        + "\nvar loader = lazy.fld_loader;"
  32.107 +        + "\nvar vm = loader.vm;"
  32.108 +        + "\nif (vm[cls]) return false;"
  32.109 +        + "\nvm[cls] = function() {"
  32.110 +        + "\n  return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2(lazy, dot);"
  32.111 +        + "\n};"
  32.112 +        + "\nreturn true;")
  32.113 +        @Override
  32.114 +        protected boolean requireReference(String internalClassName) {
  32.115 +            throw new UnsupportedOperationException();
  32.116 +        }
  32.117 +
  32.118 +        @Override
  32.119 +        protected void requireScript(String resourcePath) {
  32.120 +        }
  32.121 +
  32.122 +        @Override
  32.123 +        String assignClass(String className) {
  32.124 +            return "vm[arguments[1]]=";
  32.125 +        }
  32.126 +
  32.127 +        @Override
  32.128 +        String accessClass(String classOperation) {
  32.129 +            return "vm." + classOperation;
  32.130 +        }
  32.131 +    }
  32.132 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/BytesLoader.java	Wed Dec 12 12:41:06 2012 +0100
    33.3 @@ -0,0 +1,58 @@
    33.4 +/**
    33.5 + * Back 2 Browser Bytecode Translator
    33.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    33.7 + *
    33.8 + * This program is free software: you can redistribute it and/or modify
    33.9 + * it under the terms of the GNU General Public License as published by
   33.10 + * the Free Software Foundation, version 2 of the License.
   33.11 + *
   33.12 + * This program is distributed in the hope that it will be useful,
   33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.15 + * GNU General Public License for more details.
   33.16 + *
   33.17 + * You should have received a copy of the GNU General Public License
   33.18 + * along with this program. Look for COPYING file in the top folder.
   33.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   33.20 + */
   33.21 +package org.apidesign.vm4brwsr;
   33.22 +
   33.23 +import java.io.IOException;
   33.24 +import java.io.InputStream;
   33.25 +import java.util.Set;
   33.26 +import java.util.TreeSet;
   33.27 +
   33.28 +/**
   33.29 + *
   33.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   33.31 + */
   33.32 +public final class BytesLoader {
   33.33 +    private static Set<String> requested = new TreeSet<String>();
   33.34 +
   33.35 +    public byte[] get(String name) throws IOException {
   33.36 +        if (!requested.add(name)) {
   33.37 +            throw new IllegalStateException("Requested for second time: " + name);
   33.38 +        }
   33.39 +        InputStream is = BytesLoader.class.getClassLoader().getResourceAsStream(name);
   33.40 +        if (is == null) {
   33.41 +            throw new IOException("Can't find " + name);
   33.42 +        }
   33.43 +        byte[] arr = new byte[is.available()];
   33.44 +        int len = is.read(arr);
   33.45 +        if (len != arr.length) {
   33.46 +            throw new IOException("Read only " + len + " wanting " + arr.length);
   33.47 +        }
   33.48 +        /*
   33.49 +        System.err.print("loader['" + name + "'] = [");
   33.50 +        for (int i = 0; i < arr.length; i++) {
   33.51 +        if (i > 0) {
   33.52 +        System.err.print(", ");
   33.53 +        }
   33.54 +        System.err.print(arr[i]);
   33.55 +        }
   33.56 +        System.err.println("]");
   33.57 +         */
   33.58 +        return arr;
   33.59 +    }
   33.60 +    
   33.61 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Wed Dec 12 12:41:06 2012 +0100
    34.3 @@ -0,0 +1,138 @@
    34.4 +/**
    34.5 + * Back 2 Browser Bytecode Translator
    34.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    34.7 + *
    34.8 + * This program is free software: you can redistribute it and/or modify
    34.9 + * it under the terms of the GNU General Public License as published by
   34.10 + * the Free Software Foundation, version 2 of the License.
   34.11 + *
   34.12 + * This program is distributed in the hope that it will be useful,
   34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.15 + * GNU General Public License for more details.
   34.16 + *
   34.17 + * You should have received a copy of the GNU General Public License
   34.18 + * along with this program. Look for COPYING file in the top folder.
   34.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   34.20 + */
   34.21 +package org.apidesign.vm4brwsr;
   34.22 +
   34.23 +import javax.script.Invocable;
   34.24 +import org.testng.annotations.Test;
   34.25 +import static org.testng.Assert.*;
   34.26 +import org.testng.annotations.BeforeClass;
   34.27 +
   34.28 +/**
   34.29 + *
   34.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   34.31 + */
   34.32 +public class ClassTest {
   34.33 +
   34.34 +    @Test public void superClassEqualsGetSuperclass() {
   34.35 +        assertTrue(Classes.equalsClassesOfExceptions(), "Classes are equal");
   34.36 +    }
   34.37 +
   34.38 +    @Test public void jsSuperClassEqualsGetSuperclass() throws Exception {
   34.39 +        assertExec("Classes are equal", Classes.class, "equalsClassesOfExceptions__Z", Double.valueOf(1.0));
   34.40 +    }
   34.41 +
   34.42 +    @Test public void classesAreDifferent() {
   34.43 +        assertTrue(Classes.differenceInClasses(), "Classes are not equal");
   34.44 +    }
   34.45 +
   34.46 +    @Test public void jsClassesAreDifferent() throws Exception {
   34.47 +        assertExec("Classes are not equal", Classes.class, "differenceInClasses__Z", Double.valueOf(1.0));
   34.48 +    }
   34.49 +
   34.50 +    @Test public void javaInstanceName() throws Exception {
   34.51 +        assertEquals(Classes.classForInstance(), "java.io.IOException");
   34.52 +    }
   34.53 +    @Test public void jsInstanceName() throws Exception {
   34.54 +        assertExec("I/O name", Classes.class, "classForInstance__Ljava_lang_String_2", "java.io.IOException");
   34.55 +    }
   34.56 +    @Test public void javaName() throws Exception {
   34.57 +        assertEquals(Classes.name(), "java.io.IOException");
   34.58 +    }
   34.59 +    @Test public void jsName() throws Exception {
   34.60 +        assertExec("I/O name", Classes.class, "name__Ljava_lang_String_2", "java.io.IOException");
   34.61 +    }
   34.62 +    @Test public void javaSimpleName() throws Exception {
   34.63 +        assertEquals(Classes.simpleName(), "IOException");
   34.64 +    }
   34.65 +    @Test public void jsGetsSimpleName() throws Exception {
   34.66 +        assertExec("I/O simple name", Classes.class, "simpleName__Ljava_lang_String_2", "IOException");
   34.67 +    }
   34.68 +    @Test public void javaCanonicalName() {
   34.69 +        assertEquals(Classes.canonicalName(), "java.io.IOException");
   34.70 +    }
   34.71 +    @Test public void jsCanonicalName() throws Exception {
   34.72 +        assertExec("I/O simple name", Classes.class, "canonicalName__Ljava_lang_String_2", "java.io.IOException");
   34.73 +    }
   34.74 +    @Test public void javaNewInstance() throws Exception {
   34.75 +        assertTrue(Classes.newInstance());
   34.76 +    }
   34.77 +    @Test public void jsNewInstance() throws Exception {
   34.78 +        assertExec("Check new instance", Classes.class, "newInstance__Z", Double.valueOf(1));
   34.79 +    }
   34.80 +    @Test public void jsAnnotation() throws Exception {
   34.81 +        assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10));
   34.82 +    }
   34.83 +    @Test public void jsStringAnnotation() throws Exception {
   34.84 +        assertExec("Check class annotation", Classes.class, "getNamer__Ljava_lang_String_2Z", "my text", true);
   34.85 +    }
   34.86 +    @Test public void jsStringAnnotationFromArray() throws Exception {
   34.87 +        assertExec("Check class annotation", Classes.class, "getNamer__Ljava_lang_String_2Z", "my text", false);
   34.88 +    }
   34.89 +    @Test public void javaInvokeMethod() throws Exception {
   34.90 +        assertEquals(Classes.reflectiveMethodCall(true, "name"), "java.io.IOException", "Calls the name() method via reflection");
   34.91 +    }
   34.92 +    @Test public void jsInvokeMethod() throws Exception {
   34.93 +        assertExec("Calls the name() method via reflection", Classes.class, 
   34.94 +            "reflectiveMethodCall__Ljava_lang_Object_2ZLjava_lang_String_2", 
   34.95 +            "java.io.IOException", true, "name"
   34.96 +        );
   34.97 +    }
   34.98 +    @Test public void javaFindMethod() throws Exception {
   34.99 +        assertEquals(Classes.reflectiveMethodCall(false, "name"), "java.io.IOException", "Calls the name() method via reflection");
  34.100 +    }
  34.101 +    @Test public void jsFindMethod() throws Exception {
  34.102 +        assertExec("Calls the name() method via reflection", Classes.class, 
  34.103 +            "reflectiveMethodCall__Ljava_lang_Object_2ZLjava_lang_String_2", 
  34.104 +            "java.io.IOException", false, "name"
  34.105 +        );
  34.106 +    }
  34.107 +    @Test public void javaAnnotatedMethod() throws Exception {
  34.108 +        assertEquals(Classes.reflectiveMethodCall(false, null), "java.io.IOException", "Calls the name() method via reflection");
  34.109 +    }
  34.110 +    @Test public void jsAnnotatedMethod() throws Exception {
  34.111 +        assertExec("Calls the name() method via reflection", Classes.class, 
  34.112 +            "reflectiveMethodCall__Ljava_lang_Object_2ZLjava_lang_String_2", 
  34.113 +            "java.io.IOException", false, null
  34.114 +        );
  34.115 +    }
  34.116 +    @Test public void jsClassParam() throws Exception {
  34.117 +        assertExec("Calls the nameOfIO()", Classes.class, 
  34.118 +            "nameOfIO__Ljava_lang_String_2", 
  34.119 +            "java.io.IOException"
  34.120 +        );
  34.121 +    }
  34.122 +    
  34.123 +    private static CharSequence codeSeq;
  34.124 +    private static Invocable code;
  34.125 +    
  34.126 +    @BeforeClass
  34.127 +    public void compileTheCode() throws Exception {
  34.128 +        if (codeSeq == null) {
  34.129 +            StringBuilder sb = new StringBuilder();
  34.130 +            code = StaticMethodTest.compileClass(sb, "org/apidesign/vm4brwsr/Classes");
  34.131 +            codeSeq = sb;
  34.132 +        }
  34.133 +    }
  34.134 +    
  34.135 +    private void assertExec(
  34.136 +        String msg, Class clazz, String method, Object expRes, Object... args
  34.137 +    ) throws Exception {
  34.138 +        StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
  34.139 +    }
  34.140 +    
  34.141 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Wed Dec 12 12:41:06 2012 +0100
    35.3 @@ -0,0 +1,122 @@
    35.4 +/**
    35.5 + * Back 2 Browser Bytecode Translator
    35.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    35.7 + *
    35.8 + * This program is free software: you can redistribute it and/or modify
    35.9 + * it under the terms of the GNU General Public License as published by
   35.10 + * the Free Software Foundation, version 2 of the License.
   35.11 + *
   35.12 + * This program is distributed in the hope that it will be useful,
   35.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.15 + * GNU General Public License for more details.
   35.16 + *
   35.17 + * You should have received a copy of the GNU General Public License
   35.18 + * along with this program. Look for COPYING file in the top folder.
   35.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   35.20 + */
   35.21 +package org.apidesign.vm4brwsr;
   35.22 +
   35.23 +import java.io.IOException;
   35.24 +import java.lang.annotation.Annotation;
   35.25 +import java.lang.reflect.Method;
   35.26 +import java.net.MalformedURLException;
   35.27 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   35.28 +
   35.29 +/**
   35.30 + *
   35.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   35.32 + */
   35.33 +@ClassesMarker(number = 10)
   35.34 +@ClassesNamer(name = "my text")
   35.35 +public class Classes {
   35.36 +    public static String nameOfIO() {
   35.37 +        return nameFor(IOException.class);
   35.38 +    }
   35.39 +    
   35.40 +    private static String nameFor(Class<?> c) {
   35.41 +        return c.getName();
   35.42 +    }
   35.43 +    
   35.44 +    public static boolean equalsClassesOfExceptions() {
   35.45 +        return MalformedURLException.class.getSuperclass() == IOException.class;
   35.46 +    }
   35.47 +    public static boolean differenceInClasses() {
   35.48 +        Class<?> c1 = MalformedURLException.class;
   35.49 +        Class<?> c2 = IOException.class;
   35.50 +        return c1 != c2;
   35.51 +    }
   35.52 +    
   35.53 +    public static String classForInstance() {
   35.54 +        return new IOException().getClass().getName().toString();
   35.55 +    }
   35.56 +    
   35.57 +    @ClassesMarker(number = 1)
   35.58 +    public static String name() {
   35.59 +        return IOException.class.getName().toString();
   35.60 +    }
   35.61 +    public static String simpleName() {
   35.62 +        return IOException.class.getSimpleName();
   35.63 +    }
   35.64 +    public static String canonicalName() {
   35.65 +        return IOException.class.getCanonicalName();
   35.66 +    }
   35.67 +    public static boolean newInstance() throws Exception {
   35.68 +        IOException ioe = IOException.class.newInstance();
   35.69 +        if (ioe instanceof IOException) {
   35.70 +            return ioe.getClass() == IOException.class;
   35.71 +        }
   35.72 +        throw new IllegalStateException("Not a subtype: " + ioe);
   35.73 +    }
   35.74 +    public static int getMarker() {
   35.75 +        if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) {
   35.76 +            return -2;
   35.77 +        }
   35.78 +        ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
   35.79 +        return cm == null ? -1 : cm.number();
   35.80 +    }
   35.81 +    public static String getNamer(boolean direct) {
   35.82 +        if (direct) {
   35.83 +            ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class);
   35.84 +            return cm == null ? null : cm.name();
   35.85 +        }
   35.86 +        for (Annotation a : Classes.class.getAnnotations()) {
   35.87 +            if (a instanceof ClassesNamer) {
   35.88 +                return ((ClassesNamer)a).name();
   35.89 +            }
   35.90 +        }
   35.91 +        return null;
   35.92 +    }
   35.93 +    
   35.94 +    @JavaScriptBody(args = "msg", body = "throw msg;")
   35.95 +    private static native void thrw(String msg);
   35.96 +    
   35.97 +    public static Object reflectiveMethodCall(boolean direct, String mn) throws Exception {
   35.98 +        Method find = null;
   35.99 +        StringBuilder sb = new StringBuilder();
  35.100 +        if (!direct) {
  35.101 +            final Class<? extends Annotation> v = ClassesMarker.class;
  35.102 +            for (Method m : Classes.class.getMethods()) {
  35.103 +                sb.append("\n").append(m.getName());
  35.104 +                if (mn != null) {
  35.105 +                    if (m.getName().equals(mn)) {
  35.106 +                        find = m;
  35.107 +                        break;
  35.108 +                    }
  35.109 +                } else {
  35.110 +                    if (m.getAnnotation(v) != null) {
  35.111 +                        find = m;
  35.112 +                        break;
  35.113 +                    }
  35.114 +                }
  35.115 +            }
  35.116 +        } else {
  35.117 +            find = Classes.class.getMethod(mn);
  35.118 +        }
  35.119 +        if (find == null) {
  35.120 +            thrw(sb.toString());
  35.121 +            throw new NullPointerException(sb.toString());
  35.122 +        }
  35.123 +        return find.invoke(null);
  35.124 +    }
  35.125 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassesMarker.java	Wed Dec 12 12:41:06 2012 +0100
    36.3 @@ -0,0 +1,30 @@
    36.4 +/**
    36.5 + * Back 2 Browser Bytecode Translator
    36.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    36.7 + *
    36.8 + * This program is free software: you can redistribute it and/or modify
    36.9 + * it under the terms of the GNU General Public License as published by
   36.10 + * the Free Software Foundation, version 2 of the License.
   36.11 + *
   36.12 + * This program is distributed in the hope that it will be useful,
   36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.15 + * GNU General Public License for more details.
   36.16 + *
   36.17 + * You should have received a copy of the GNU General Public License
   36.18 + * along with this program. Look for COPYING file in the top folder.
   36.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   36.20 + */
   36.21 +package org.apidesign.vm4brwsr;
   36.22 +
   36.23 +import java.lang.annotation.Retention;
   36.24 +import java.lang.annotation.RetentionPolicy;
   36.25 +
   36.26 +/**
   36.27 + *
   36.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   36.29 + */
   36.30 +@Retention(RetentionPolicy.RUNTIME)
   36.31 +public @interface ClassesMarker {
   36.32 +    int number();
   36.33 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassesNamer.java	Wed Dec 12 12:41:06 2012 +0100
    37.3 @@ -0,0 +1,30 @@
    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 java.lang.annotation.Retention;
   37.24 +import java.lang.annotation.RetentionPolicy;
   37.25 +
   37.26 +/**
   37.27 + *
   37.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   37.29 + */
   37.30 +@Retention(RetentionPolicy.RUNTIME)
   37.31 +public @interface ClassesNamer {
   37.32 +    String name();
   37.33 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Compare.java	Wed Dec 12 12:41:06 2012 +0100
    38.3 @@ -0,0 +1,36 @@
    38.4 +/**
    38.5 + * Back 2 Browser Bytecode Translator
    38.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    38.7 + *
    38.8 + * This program is free software: you can redistribute it and/or modify
    38.9 + * it under the terms of the GNU General Public License as published by
   38.10 + * the Free Software Foundation, version 2 of the License.
   38.11 + *
   38.12 + * This program is distributed in the hope that it will be useful,
   38.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   38.15 + * GNU General Public License for more details.
   38.16 + *
   38.17 + * You should have received a copy of the GNU General Public License
   38.18 + * along with this program. Look for COPYING file in the top folder.
   38.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   38.20 + */
   38.21 +package org.apidesign.vm4brwsr;
   38.22 +
   38.23 +import java.lang.annotation.ElementType;
   38.24 +import java.lang.annotation.Retention;
   38.25 +import java.lang.annotation.RetentionPolicy;
   38.26 +import java.lang.annotation.Target;
   38.27 +
   38.28 +/** Can be applied on a method that yields a return value. 
   38.29 + * Together with {@link VMCompare#create} it can be used to write
   38.30 + * methods which are executed in real as well as JavaScript VMs and
   38.31 + * their results are compared.
   38.32 + *
   38.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   38.34 + */
   38.35 +@Retention(RetentionPolicy.RUNTIME)
   38.36 +@Target(ElementType.METHOD)
   38.37 +public @interface Compare {
   38.38 +    
   38.39 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java	Wed Dec 12 12:41:06 2012 +0100
    39.3 @@ -0,0 +1,197 @@
    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 +package org.apidesign.vm4brwsr;
   39.22 +
   39.23 +import java.lang.reflect.Method;
   39.24 +import java.util.Map;
   39.25 +import java.util.WeakHashMap;
   39.26 +import javax.script.Invocable;
   39.27 +import javax.script.ScriptContext;
   39.28 +import javax.script.ScriptEngine;
   39.29 +import javax.script.ScriptEngineManager;
   39.30 +import org.testng.Assert;
   39.31 +import org.testng.ITest;
   39.32 +import org.testng.annotations.Factory;
   39.33 +import org.testng.annotations.Test;
   39.34 +
   39.35 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
   39.36 + * in provided class and builds set of tests that compare the computations
   39.37 + * in real as well as JavaScript virtual machines. Use as:<pre>
   39.38 + * {@code @}{@link Factory} public static create() {
   39.39 + *   return @{link CompareVMs}.{@link #create(YourClass.class);
   39.40 + * }</pre>
   39.41 + *
   39.42 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   39.43 + */
   39.44 +public final class CompareVMs implements ITest {
   39.45 +    private final Run first, second;
   39.46 +    private final Method m;
   39.47 +    
   39.48 +    private CompareVMs(Method m, Run first, Run second) {
   39.49 +        this.first = first;
   39.50 +        this.second = second;
   39.51 +        this.m = m;
   39.52 +    }
   39.53 +
   39.54 +    public static Object[] create(Class<?> clazz) {
   39.55 +        Method[] arr = clazz.getMethods();
   39.56 +        Object[] ret = new Object[3 * arr.length];
   39.57 +        int cnt = 0;
   39.58 +        for (Method m : arr) {
   39.59 +            Compare c = m.getAnnotation(Compare.class);
   39.60 +            if (c == null) {
   39.61 +                continue;
   39.62 +            }
   39.63 +            final Run real = new Run(m, false);
   39.64 +            final Run js = new Run(m, true);
   39.65 +            ret[cnt++] = real;
   39.66 +            ret[cnt++] = js;
   39.67 +            ret[cnt++] = new CompareVMs(m, real, js);
   39.68 +        }
   39.69 +        Object[] r = new Object[cnt];
   39.70 +        for (int i = 0; i < cnt; i++) {
   39.71 +            r[i] = ret[i];
   39.72 +        }
   39.73 +        return r;
   39.74 +    }
   39.75 +    
   39.76 +    @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
   39.77 +        Object v1 = first.value;
   39.78 +        Object v2 = second.value;
   39.79 +        if (v1 instanceof Number) {
   39.80 +            v1 = ((Number)v1).doubleValue();
   39.81 +        }
   39.82 +        Assert.assertEquals(v2, v1, "Comparing results");
   39.83 +    }
   39.84 +    
   39.85 +    @Override
   39.86 +    public String getTestName() {
   39.87 +        return m.getName() + "[Compare]";
   39.88 +    }
   39.89 +    
   39.90 +    public static final class Run implements ITest {
   39.91 +        private final Method m;
   39.92 +        private final boolean js;
   39.93 +        Object value;
   39.94 +        private Invocable code;
   39.95 +        private CharSequence codeSeq;
   39.96 +        private static final Map<Class,Object[]> compiled = new WeakHashMap<Class,Object[]>();
   39.97 +
   39.98 +        private Run(Method m, boolean js) {
   39.99 +            this.m = m;
  39.100 +            this.js = js;
  39.101 +        }
  39.102 +
  39.103 +        private void compileTheCode(Class<?> clazz) throws Exception {
  39.104 +            final Object[] data = compiled.get(clazz);
  39.105 +            if (data != null) {
  39.106 +                code = (Invocable) data[0];
  39.107 +                codeSeq = (CharSequence) data[1];
  39.108 +                return;
  39.109 +            }
  39.110 +            StringBuilder sb = new StringBuilder();
  39.111 +            Bck2Brwsr.generate(sb, CompareVMs.class.getClassLoader());
  39.112 +
  39.113 +            ScriptEngineManager sem = new ScriptEngineManager();
  39.114 +            ScriptEngine js = sem.getEngineByExtension("js");
  39.115 +            js.getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
  39.116 +            
  39.117 +            sb.append("\nfunction initVM() {"
  39.118 +                + "\n  return bck2brwsr("
  39.119 +                + "\n    function(name) { return loader.get(name);}"
  39.120 +                + "\n  );"
  39.121 +                + "\n};");
  39.122 +
  39.123 +            Object res = js.eval(sb.toString());
  39.124 +            Assert.assertTrue(js instanceof Invocable, "It is invocable object: " + res);
  39.125 +            code = (Invocable) js;
  39.126 +            codeSeq = sb;
  39.127 +            compiled.put(clazz, new Object[] { code, codeSeq });
  39.128 +        }
  39.129 +
  39.130 +        @Test(groups = "run") public void executeCode() throws Throwable {
  39.131 +            if (js) {
  39.132 +                try {
  39.133 +                    compileTheCode(m.getDeclaringClass());
  39.134 +                    Object vm = code.invokeFunction("initVM");
  39.135 +                    Object inst = code.invokeMethod(vm, "loadClass", m.getDeclaringClass().getName());
  39.136 +                    value = code.invokeMethod(inst, m.getName() + "__" + computeSignature(m));
  39.137 +                } catch (Exception ex) {
  39.138 +                    throw new AssertionError(StaticMethodTest.dumpJS(codeSeq)).initCause(ex);
  39.139 +                }
  39.140 +            } else {
  39.141 +                value = m.invoke(m.getDeclaringClass().newInstance());
  39.142 +            }
  39.143 +        }
  39.144 +        @Override
  39.145 +        public String getTestName() {
  39.146 +            return m.getName() + (js ? "[JavaScript]" : "[Java]");
  39.147 +        }
  39.148 +        
  39.149 +        private static String computeSignature(Method m) {
  39.150 +            StringBuilder sb = new StringBuilder();
  39.151 +            appendType(sb, m.getReturnType());
  39.152 +            for (Class<?> c : m.getParameterTypes()) {
  39.153 +                appendType(sb, c);
  39.154 +            }
  39.155 +            return sb.toString();
  39.156 +        }
  39.157 +        
  39.158 +        private static void appendType(StringBuilder sb, Class<?> t) {
  39.159 +            if (t == null) {
  39.160 +                sb.append('V');
  39.161 +                return;
  39.162 +            }
  39.163 +            if (t.isPrimitive()) {
  39.164 +                int ch = -1;
  39.165 +                if (t == int.class) {
  39.166 +                    ch = 'I';
  39.167 +                }
  39.168 +                if (t == short.class) {
  39.169 +                    ch = 'S';
  39.170 +                }
  39.171 +                if (t == byte.class) {
  39.172 +                    ch = 'B';
  39.173 +                }
  39.174 +                if (t == boolean.class) {
  39.175 +                    ch = 'Z';
  39.176 +                }
  39.177 +                if (t == long.class) {
  39.178 +                    ch = 'J';
  39.179 +                }
  39.180 +                if (t == float.class) {
  39.181 +                    ch = 'F';
  39.182 +                }
  39.183 +                if (t == double.class) {
  39.184 +                    ch = 'D';
  39.185 +                }
  39.186 +                assert ch != -1 : "Unknown primitive type " + t;
  39.187 +                sb.append((char)ch);
  39.188 +                return;
  39.189 +            }
  39.190 +            if (t.isArray()) {
  39.191 +                sb.append("_3");
  39.192 +                appendType(sb, t.getComponentType());
  39.193 +                return;
  39.194 +            }
  39.195 +            sb.append('L');
  39.196 +            sb.append(t.getName().replace('.', '_'));
  39.197 +            sb.append("_2");
  39.198 +        }
  39.199 +    }
  39.200 +}
    40.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Wed Dec 12 12:37:41 2012 +0100
    40.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Wed Dec 12 12:41:06 2012 +0100
    40.3 @@ -161,7 +161,8 @@
    40.4  
    40.5          Object ret = null;
    40.6          try {
    40.7 -            ret = code.invokeFunction(clazz.getName().replace('.', '_'), true);
    40.8 +            ret = code.invokeFunction("bck2brwsr");
    40.9 +            ret = code.invokeMethod(ret, "loadClass", clazz.getName());
   40.10              ret = code.invokeMethod(ret, method, args);
   40.11          } catch (ScriptException ex) {
   40.12              fail("Execution failed in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
    41.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Wed Dec 12 12:37:41 2012 +0100
    41.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Wed Dec 12 12:41:06 2012 +0100
    41.3 @@ -106,6 +106,11 @@
    41.4          throw new IllegalStateException();
    41.5      }
    41.6      
    41.7 +    public static String castNull(boolean n) {
    41.8 +        Object value = n ? null : "Ahoj";
    41.9 +        return (String)value;
   41.10 +    }
   41.11 +    
   41.12      public static String swtch(int what) {
   41.13          switch (what) {
   41.14              case 0: return "Jarda";
    42.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Wed Dec 12 12:37:41 2012 +0100
    42.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Wed Dec 12 12:41:06 2012 +0100
    42.3 @@ -20,6 +20,9 @@
    42.4  import java.io.File;
    42.5  import java.io.FileWriter;
    42.6  import java.io.IOException;
    42.7 +import java.io.InputStream;
    42.8 +import java.net.URL;
    42.9 +import java.util.Enumeration;
   42.10  import javax.script.Invocable;
   42.11  import javax.script.ScriptEngine;
   42.12  import javax.script.ScriptEngineManager;
   42.13 @@ -238,6 +241,13 @@
   42.14          );
   42.15      }
   42.16      
   42.17 +    @Test public void checkNullCast() throws Exception {
   42.18 +        assertExec("Null can be cast to any type",
   42.19 +            StaticMethod.class, "castNull__Ljava_lang_String_2Z", 
   42.20 +            null, true
   42.21 +        );
   42.22 +    }
   42.23 +    
   42.24      private static CharSequence codeSeq;
   42.25      private static Invocable code;
   42.26      
   42.27 @@ -262,7 +272,8 @@
   42.28      ) throws Exception {
   42.29          Object ret = null;
   42.30          try {
   42.31 -            ret = toRun.invokeFunction(clazz.getName().replace('.', '_'), true);
   42.32 +            ret = toRun.invokeFunction("bck2brwsr");
   42.33 +            ret = toRun.invokeMethod(ret, "loadClass", clazz.getName());
   42.34              ret = toRun.invokeMethod(ret, method, args);
   42.35          } catch (ScriptException ex) {
   42.36              fail("Execution failed in\n" + dumpJS(theCode), ex);
   42.37 @@ -288,7 +299,7 @@
   42.38          if (sb == null) {
   42.39              sb = new StringBuilder();
   42.40          }
   42.41 -        GenJS.compile(sb, names);
   42.42 +        Bck2Brwsr.generate(sb, new EmulationResources(), names);
   42.43          ScriptEngineManager sem = new ScriptEngineManager();
   42.44          ScriptEngine js = sem.getEngineByExtension("js");
   42.45          if (eng != null) {
   42.46 @@ -313,4 +324,21 @@
   42.47          w.close();
   42.48          return new StringBuilder(f.getPath());
   42.49      }
   42.50 +    private static class EmulationResources implements Bck2Brwsr.Resources {
   42.51 +        @Override
   42.52 +        public InputStream get(String name) throws IOException {
   42.53 +            Enumeration<URL> en = StaticMethodTest.class.getClassLoader().getResources(name);
   42.54 +            URL u = null;
   42.55 +            while (en.hasMoreElements()) {
   42.56 +                u = en.nextElement();
   42.57 +            }
   42.58 +            if (u == null) {
   42.59 +                throw new IOException("Can't find " + name);
   42.60 +            }
   42.61 +            if (u.toExternalForm().contains("rt.jar!")) {
   42.62 +                throw new IOException("No emulation for " + u);
   42.63 +            }
   42.64 +            return u.openStream();
   42.65 +        }
   42.66 +    }
   42.67  }
    43.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java	Wed Dec 12 12:37:41 2012 +0100
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,68 +0,0 @@
    43.4 -/**
    43.5 - * Back 2 Browser Bytecode Translator
    43.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    43.7 - *
    43.8 - * This program is free software: you can redistribute it and/or modify
    43.9 - * it under the terms of the GNU General Public License as published by
   43.10 - * the Free Software Foundation, version 2 of the License.
   43.11 - *
   43.12 - * This program is distributed in the hope that it will be useful,
   43.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.15 - * GNU General Public License for more details.
   43.16 - *
   43.17 - * You should have received a copy of the GNU General Public License
   43.18 - * along with this program. Look for COPYING file in the top folder.
   43.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   43.20 - */
   43.21 -package org.apidesign.vm4brwsr;
   43.22 -
   43.23 -import java.io.ByteArrayInputStream;
   43.24 -import java.io.IOException;
   43.25 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   43.26 -
   43.27 -/**
   43.28 - *
   43.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   43.30 - */
   43.31 -class VMLazy extends ByteCodeToJavaScript {
   43.32 -    private final Object vm;
   43.33 -    private final Object global;
   43.34 -    
   43.35 -    private VMLazy(Object global, Object vm, Appendable out) {
   43.36 -        super(out);
   43.37 -        this.vm = vm;
   43.38 -        this.global = global;
   43.39 -    }
   43.40 -    
   43.41 -    static String toJavaScript(Object global, Object vm, byte[] is) throws IOException {
   43.42 -        StringBuilder sb = new StringBuilder();
   43.43 -        new VMLazy(global, vm, sb).compile(new ByteArrayInputStream(is));
   43.44 -        return sb.toString().toString();
   43.45 -    }
   43.46 -
   43.47 -    @JavaScriptBody(args = { "self", "n" }, 
   43.48 -        body=
   43.49 -          "var cls = n.replace__Ljava_lang_String_2CC(n,'/','_').toString();"
   43.50 -        + "var glb = self.fld_global;"
   43.51 -        + "var vm = self.fld_vm;"
   43.52 -        + "if (glb[cls]) return false;"
   43.53 -        + "glb[cls] = function() {"
   43.54 -        + "  return vm.loadClass(n,cls);"
   43.55 -        + "};"
   43.56 -        + "return true;"
   43.57 -    )
   43.58 -    @Override
   43.59 -    protected boolean requireReference(String internalClassName) {
   43.60 -        throw new UnsupportedOperationException();
   43.61 -    }
   43.62 -
   43.63 -    @Override
   43.64 -    protected void requireScript(String resourcePath) {
   43.65 -    }
   43.66 -
   43.67 -    @Override
   43.68 -    protected String assignClass(String className) {
   43.69 -        return "arguments[0][arguments[1]]=";
   43.70 -    }
   43.71 -}
    44.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java	Wed Dec 12 12:37:41 2012 +0100
    44.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java	Wed Dec 12 12:41:06 2012 +0100
    44.3 @@ -17,8 +17,6 @@
    44.4   */
    44.5  package org.apidesign.vm4brwsr;
    44.6  
    44.7 -import java.io.IOException;
    44.8 -import java.io.InputStream;
    44.9  import javax.script.Invocable;
   44.10  import javax.script.ScriptContext;
   44.11  import javax.script.ScriptEngine;
   44.12 @@ -40,50 +38,32 @@
   44.13      @BeforeClass
   44.14      public void compileTheCode() throws Exception {
   44.15          StringBuilder sb = new StringBuilder();
   44.16 -        
   44.17 -        sb.append("\nfunction test(clazz, as, method) {");
   44.18 -        sb.append("\n  var l = new lazyVM(this);");
   44.19 -        sb.append("\n  var c = l.loadClass(clazz, as);");
   44.20 +        sb.append("\nvar data = {};");
   44.21 +        sb.append("\nfunction test(clazz, method) {");
   44.22 +        sb.append("\n  if (!data.bck2brwsr) data.bck2brwsr = bck2brwsr(function(name) { return loader.get(name); });");
   44.23 +        sb.append("\n  var c = data.bck2brwsr.loadClass(clazz);");
   44.24          sb.append("\n  return c[method]();");
   44.25          sb.append("\n}");
   44.26          
   44.27          
   44.28 -        sb.append("\nfunction lazyVM(global) {");
   44.29 -        sb.append("\n  var self = this;");
   44.30 -        sb.append("\n  var glb = global;");
   44.31 -        sb.append("\n  lazyVM.prototype.loadClass = function(res, name) {");
   44.32 -        sb.append("\n    var script = org_apidesign_vm4brwsr_VMLazy(true)."
   44.33 -            + "toJavaScript__Ljava_lang_String_2Ljava_lang_Object_2Ljava_lang_Object_2_3B("
   44.34 -            + "  glb, self,"
   44.35 -            + "  loader.get(res + '.class')"
   44.36 -            + ");");
   44.37 -        sb.append("\n    try {");
   44.38 -        sb.append("\n      new Function(script)(glb, name);");
   44.39 -        sb.append("\n    } catch (ex) {");
   44.40 -        sb.append("\n      throw 'Cannot compile ' + res + ' error: ' + ex + ' script:\\n' + script;");
   44.41 -        sb.append("\n    };");
   44.42 -        sb.append("\n    return glb[name](true);");
   44.43 -        sb.append("\n  };");
   44.44 -        sb.append("\n");
   44.45 -        sb.append("\n}\n");
   44.46 -        
   44.47 +       
   44.48          ScriptEngine[] arr = { null };
   44.49          code = StaticMethodTest.compileClass(sb, arr,
   44.50 -            "org/apidesign/vm4brwsr/VMLazy"
   44.51 +            "org/apidesign/vm4brwsr/VM"
   44.52          );
   44.53 -        arr[0].getContext().setAttribute("loader", new FindBytes(), ScriptContext.ENGINE_SCOPE);
   44.54 +        arr[0].getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
   44.55          codeSeq = sb;
   44.56      }
   44.57      
   44.58      @Test public void invokeStaticMethod() throws Exception {
   44.59          assertExec("Trying to get -1", "test", Double.valueOf(-1),
   44.60 -            "org/apidesign/vm4brwsr/StaticMethod", "org_apidesign_vm4brwsr_StaticMethod", "minusOne__I"
   44.61 +            StaticMethod.class.getName(), "minusOne__I"
   44.62          );
   44.63      }
   44.64  
   44.65      @Test public void loadDependantClass() throws Exception {
   44.66 -        assertExec("Trying to get zero", "test", Double.valueOf(0),
   44.67 -            "org/apidesign/vm4brwsr/InstanceSub", "org_apidesign_vm4brwsr_InstanceSub", "recallDbl__D"
   44.68 +        assertExec("Expecting zero", "test", Double.valueOf(0),
   44.69 +            InstanceSub.class.getName(), "recallDbl__D"
   44.70          );
   44.71      }
   44.72  
   44.73 @@ -104,29 +84,4 @@
   44.74          }
   44.75          assertEquals(ret, expRes, msg + "was: " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq));
   44.76      }
   44.77 -
   44.78 -    public static final class FindBytes {
   44.79 -        public byte[] get(String name) throws IOException {
   44.80 -            InputStream is = VMLazyTest.class.getClassLoader().getResourceAsStream(name);
   44.81 -            if (is == null) {
   44.82 -                throw new IOException("Can't find " + name);
   44.83 -            }
   44.84 -            byte[] arr = new byte[is.available()];
   44.85 -            int len = is.read(arr);
   44.86 -            if (len != arr.length) {
   44.87 -                throw new IOException("Read only " + len + " wanting " + arr.length);
   44.88 -            }
   44.89 -            /*
   44.90 -            System.err.print("loader['" + name + "'] = [");
   44.91 -            for (int i = 0; i < arr.length; i++) {
   44.92 -                if (i > 0) {
   44.93 -                    System.err.print(", ");
   44.94 -                }
   44.95 -                System.err.print(arr[i]);
   44.96 -            }
   44.97 -            System.err.println("]");
   44.98 -            */
   44.99 -            return arr;
  44.100 -        }
  44.101 -    }
  44.102  }
    45.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java	Wed Dec 12 12:37:41 2012 +0100
    45.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java	Wed Dec 12 12:41:06 2012 +0100
    45.3 @@ -35,13 +35,43 @@
    45.4      private static CharSequence codeSeq;
    45.5      private static Invocable code;
    45.6      
    45.7 -    @Test public void compareTheGeneratedCode() throws Exception {
    45.8 -        byte[] arr = readClass("/org/apidesign/vm4brwsr/Array.class");
    45.9 +    @Test public void compareGeneratedCodeForArrayClass() throws Exception {
   45.10 +        compareCode("/org/apidesign/vm4brwsr/Array.class");
   45.11 +    }
   45.12 +
   45.13 +    @Test public void compareGeneratedCodeForClassesClass() throws Exception {
   45.14 +        compareCode("/org/apidesign/vm4brwsr/Classes.class");
   45.15 +    }
   45.16 +    
   45.17 +    @BeforeClass
   45.18 +    public void compileTheCode() throws Exception {
   45.19 +        StringBuilder sb = new StringBuilder();
   45.20 +        code = StaticMethodTest.compileClass(sb, 
   45.21 +            "org/apidesign/vm4brwsr/VMinVM"
   45.22 +        );
   45.23 +        codeSeq = sb;
   45.24 +    }
   45.25 +    
   45.26 +    private static byte[] readClass(String res) throws IOException {
   45.27 +        InputStream is1 = VMinVMTest.class.getResourceAsStream(res);
   45.28 +        assertNotNull(is1, "Stream found");
   45.29 +        byte[] arr = new byte[is1.available()];
   45.30 +        int len = is1.read(arr);
   45.31 +        is1.close();
   45.32 +        if (len != arr.length) {
   45.33 +            throw new IOException("Wrong len " + len + " for arr: " + arr.length);
   45.34 +        }
   45.35 +        return arr;
   45.36 +    }
   45.37 +
   45.38 +    private void compareCode(final String nm) throws Exception, IOException {
   45.39 +        byte[] arr = readClass(nm);
   45.40          String ret1 = VMinVM.toJavaScript(arr);
   45.41          
   45.42          Object ret;
   45.43          try {
   45.44 -            ret = code.invokeFunction(VMinVM.class.getName().replace('.', '_'), true);
   45.45 +            ret = code.invokeFunction("bck2brwsr");
   45.46 +            ret = code.invokeMethod(ret, "loadClass", VMinVM.class.getName());
   45.47              ret = code.invokeMethod(ret, "toJavaScript__Ljava_lang_String_2_3B", arr);
   45.48          } catch (Exception ex) {
   45.49              File f = File.createTempFile("execution", ".js");
   45.50 @@ -64,27 +94,14 @@
   45.51          
   45.52          assertTrue(ret instanceof String, "It is string: " + ret);
   45.53          
   45.54 -        assertEquals((String)ret, ret1.toString(), "The code is the same");
   45.55 -    }
   45.56 -    
   45.57 -    @BeforeClass
   45.58 -    public void compileTheCode() throws Exception {
   45.59 -        StringBuilder sb = new StringBuilder();
   45.60 -        code = StaticMethodTest.compileClass(sb, 
   45.61 -            "org/apidesign/vm4brwsr/VMinVM"
   45.62 -        );
   45.63 -        codeSeq = sb;
   45.64 -    }
   45.65 -    
   45.66 -    private static byte[] readClass(String res) throws IOException {
   45.67 -        InputStream is1 = VMinVMTest.class.getResourceAsStream(res);
   45.68 -        assertNotNull(is1, "Stream found");
   45.69 -        byte[] arr = new byte[is1.available()];
   45.70 -        int len = is1.read(arr);
   45.71 -        is1.close();
   45.72 -        if (len != arr.length) {
   45.73 -            throw new IOException("Wrong len " + len + " for arr: " + arr.length);
   45.74 +        if (!ret1.toString().equals(ret)) {
   45.75 +            StringBuilder msg = new StringBuilder("Difference found between ");
   45.76 +            msg.append(StaticMethodTest.dumpJS(ret1));
   45.77 +            msg.append(" ");
   45.78 +            msg.append(StaticMethodTest.dumpJS((CharSequence) ret));
   45.79 +            msg.append(" compiled by ");
   45.80 +            msg.append(StaticMethodTest.dumpJS(codeSeq));
   45.81 +            fail(msg.toString());
   45.82          }
   45.83 -        return arr;
   45.84      }
   45.85  }
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareHashTest.java	Wed Dec 12 12:41:06 2012 +0100
    46.3 @@ -0,0 +1,37 @@
    46.4 +/**
    46.5 + * Back 2 Browser Bytecode Translator
    46.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    46.7 + *
    46.8 + * This program is free software: you can redistribute it and/or modify
    46.9 + * it under the terms of the GNU General Public License as published by
   46.10 + * the Free Software Foundation, version 2 of the License.
   46.11 + *
   46.12 + * This program is distributed in the hope that it will be useful,
   46.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.15 + * GNU General Public License for more details.
   46.16 + *
   46.17 + * You should have received a copy of the GNU General Public License
   46.18 + * along with this program. Look for COPYING file in the top folder.
   46.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   46.20 + */
   46.21 +package org.apidesign.vm4brwsr.tck;
   46.22 +
   46.23 +import org.apidesign.vm4brwsr.Compare;
   46.24 +import org.apidesign.vm4brwsr.CompareVMs;
   46.25 +import org.testng.annotations.Factory;
   46.26 +
   46.27 +/**
   46.28 + *
   46.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   46.30 + */
   46.31 +public class CompareHashTest {
   46.32 +    @Compare public int hashOfString() {
   46.33 +        return "Ahoj".hashCode();
   46.34 +    }
   46.35 +    
   46.36 +    @Factory
   46.37 +    public static Object[] create() {
   46.38 +        return CompareVMs.create(CompareHashTest.class);
   46.39 +    }
   46.40 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareStringsTest.java	Wed Dec 12 12:41:06 2012 +0100
    47.3 @@ -0,0 +1,43 @@
    47.4 +/**
    47.5 + * Back 2 Browser Bytecode Translator
    47.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    47.7 + *
    47.8 + * This program is free software: you can redistribute it and/or modify
    47.9 + * it under the terms of the GNU General Public License as published by
   47.10 + * the Free Software Foundation, version 2 of the License.
   47.11 + *
   47.12 + * This program is distributed in the hope that it will be useful,
   47.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.15 + * GNU General Public License for more details.
   47.16 + *
   47.17 + * You should have received a copy of the GNU General Public License
   47.18 + * along with this program. Look for COPYING file in the top folder.
   47.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   47.20 + */
   47.21 +package org.apidesign.vm4brwsr.tck;
   47.22 +
   47.23 +import org.apidesign.vm4brwsr.Compare;
   47.24 +import org.apidesign.vm4brwsr.CompareVMs;
   47.25 +import org.testng.annotations.Factory;
   47.26 +
   47.27 +/**
   47.28 + *
   47.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   47.30 + */
   47.31 +public class CompareStringsTest {
   47.32 +    @Compare public String deleteLastTwoCharacters() {
   47.33 +        StringBuilder sb = new StringBuilder();
   47.34 +        sb.append("453.0");
   47.35 +        if (sb.toString().endsWith(".0")) {
   47.36 +            final int l = sb.length();
   47.37 +            sb.delete(l - 2, l);
   47.38 +        }
   47.39 +        return sb.toString().toString();
   47.40 +    }
   47.41 +    
   47.42 +    @Factory
   47.43 +    public static Object[] create() {
   47.44 +        return CompareVMs.create(CompareStringsTest.class);
   47.45 +    }
   47.46 +}