Lambda's work OK in AOT mode. Defender methods work OK. Merging.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 13 Sep 2014 18:33:05 +0200
changeset 1688e709c530c227
parent 1677 7a9492920b61
parent 1687 baa80d712c77
child 1689 4440cfbcbee7
Lambda's work OK in AOT mode. Defender methods work OK. Merging.
rt/emul/compact/src/main/java/java/lang/Cloneable.java
rt/emul/compact/src/main/java/java/lang/IncompatibleClassChangeError.java
rt/emul/mini/src/main/java/java/lang/Class.java
rt/emul/mini/src/main/java/java/lang/Cloneable.java
rt/emul/mini/src/main/java/java/lang/IncompatibleClassChangeError.java
rt/emul/mini/src/main/java/java/lang/NoSuchMethodException.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
     1.1 --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java	Tue Sep 09 12:45:22 2014 +0200
     1.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java	Sat Sep 13 18:33:05 2014 +0200
     1.3 @@ -77,26 +77,9 @@
     1.4          }
     1.5          if (s != null) {
     1.6              File root = new File(s);
     1.7 -            List<String> arr = new ArrayList<>();
     1.8 -            List<String> classes = new ArrayList<>();
     1.9 -            listDir(root, null, classes, arr);
    1.10              StringWriter w = new StringWriter();
    1.11              try {
    1.12 -                Bck2Brwsr.newCompiler()
    1.13 -                    .addRootClasses(classes.toArray(new String[0]))
    1.14 -                    .addResources(arr.toArray(new String[0]))
    1.15 -                    .library()
    1.16 -                    //.obfuscation(ObfuscationLevel.FULL)
    1.17 -                    .resources(new EmulationResources() {
    1.18 -                        @Override
    1.19 -                        public InputStream get(String resource) throws IOException {
    1.20 -                            if (r != null) {
    1.21 -                                final URL url = r.get(resource, 0);
    1.22 -                                return url == null ? null : url.openStream();
    1.23 -                            }
    1.24 -                            return super.get(resource);
    1.25 -                        }
    1.26 -                    })
    1.27 +                Bck2BrwsrJars.configureFrom(null, root)
    1.28                      .generate(w);
    1.29                  w.flush();
    1.30                  return w.toString();
    1.31 @@ -109,23 +92,6 @@
    1.32          return null;
    1.33      }
    1.34      
    1.35 -
    1.36 -    private static void listDir(File f, String pref, List<String> classes, List<String> resources) throws IOException {
    1.37 -        File[] arr = f.listFiles();
    1.38 -        if (arr == null) {
    1.39 -            if (f.getName().endsWith(".class")) {
    1.40 -                classes.add(pref + f.getName().substring(0, f.getName().length() - 6));
    1.41 -            } else {
    1.42 -                resources.add(pref + f.getName());
    1.43 -            }
    1.44 -        } else {
    1.45 -            for (File ch : arr) {
    1.46 -                
    1.47 -                listDir(ch, pref == null ? "" : pref + f.getName() + "/", classes, resources);
    1.48 -            }
    1.49 -        }
    1.50 -    }
    1.51 -
    1.52      static void compileVM(StringBuilder sb, final Res r) throws IOException {
    1.53          final Bck2Brwsr rt;
    1.54          try {
    1.55 @@ -155,26 +121,4 @@
    1.56                  }
    1.57              }).generate(sb);
    1.58      }
    1.59 -
    1.60 -    static class EmulationResources implements Bck2Brwsr.Resources {
    1.61 -
    1.62 -        @Override
    1.63 -        public InputStream get(String name) throws IOException {
    1.64 -            Enumeration<URL> en = Bck2BrwsrJars.class.getClassLoader().getResources(name);
    1.65 -            URL u = null;
    1.66 -            while (en.hasMoreElements()) {
    1.67 -                u = en.nextElement();
    1.68 -            }
    1.69 -            if (u == null) {
    1.70 -                LOG.log(Level.WARNING, "Cannot find {0}", name);
    1.71 -                return null;
    1.72 -            }
    1.73 -            if (u.toExternalForm().contains("/rt.jar!")) {
    1.74 -                LOG.log(Level.WARNING, "{0}No bootdelegation for ", name);
    1.75 -                return null;
    1.76 -            }
    1.77 -            return u.openStream();
    1.78 -        }
    1.79 -    }
    1.80 -    
    1.81  }
     2.1 --- a/rt/aot/pom.xml	Tue Sep 09 12:45:22 2014 +0200
     2.2 +++ b/rt/aot/pom.xml	Sat Sep 13 18:33:05 2014 +0200
     2.3 @@ -27,5 +27,11 @@
     2.4              <version>${project.version}</version>
     2.5              <type>jar</type>
     2.6          </dependency>
     2.7 +        <dependency>
     2.8 +            <groupId>net.orfjackal.retrolambda</groupId>
     2.9 +            <artifactId>retrolambda</artifactId>
    2.10 +            <version>1.6.1</version>
    2.11 +            <type>jar</type>
    2.12 +        </dependency>
    2.13      </dependencies>
    2.14  </project>
     3.1 --- a/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java	Tue Sep 09 12:45:22 2014 +0200
     3.2 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java	Sat Sep 13 18:33:05 2014 +0200
     3.3 @@ -18,15 +18,19 @@
     3.4  package org.apidesign.bck2brwsr.aot;
     3.5  
     3.6  import java.io.BufferedReader;
     3.7 +import java.io.ByteArrayInputStream;
     3.8  import java.io.File;
     3.9 +import java.io.FileInputStream;
    3.10  import java.io.IOException;
    3.11  import java.io.InputStream;
    3.12  import java.io.InputStreamReader;
    3.13  import java.net.URL;
    3.14  import java.util.ArrayList;
    3.15  import java.util.Enumeration;
    3.16 +import java.util.HashMap;
    3.17  import java.util.HashSet;
    3.18  import java.util.List;
    3.19 +import java.util.Map;
    3.20  import java.util.Set;
    3.21  import java.util.jar.JarEntry;
    3.22  import java.util.jar.JarFile;
    3.23 @@ -43,7 +47,7 @@
    3.24   */
    3.25  public final class Bck2BrwsrJars {
    3.26      private static final Logger LOG = Logger.getLogger(Bck2BrwsrJars.class.getName());
    3.27 -    
    3.28 +
    3.29      private Bck2BrwsrJars() {
    3.30      }
    3.31      
    3.32 @@ -64,24 +68,30 @@
    3.33       * @throws IOException if something goes wrong
    3.34       */
    3.35      public static Bck2Brwsr configureFrom(Bck2Brwsr c, File jar) throws IOException {
    3.36 +        if (jar.isDirectory()) {
    3.37 +            return configureDir(c, jar);
    3.38 +        }
    3.39          final JarFile jf = new JarFile(jar);
    3.40 -        List<String> classes = new ArrayList<>();
    3.41 +        final List<String> classes = new ArrayList<>();
    3.42          List<String> resources = new ArrayList<>();
    3.43          Set<String> exported = new HashSet<>();
    3.44 -
    3.45 -        listJAR(jf, classes, resources, exported);
    3.46 -        
    3.47 -        String cp = jf.getManifest().getMainAttributes().getValue("Class-Path"); // NOI18N
    3.48 -        String[] classpath = cp == null ? new String[0] : cp.split(" ");
    3.49 -
    3.50          class JarRes extends EmulationResources implements Bck2Brwsr.Resources {
    3.51 -
    3.52 +            JarRes() {
    3.53 +                super(classes);
    3.54 +            }
    3.55              @Override
    3.56              public InputStream get(String resource) throws IOException {
    3.57                  InputStream is = jf.getInputStream(new ZipEntry(resource));
    3.58                  return is == null ? super.get(resource) : is;
    3.59              }
    3.60          }
    3.61 +        JarRes jarRes = new JarRes();
    3.62 +
    3.63 +        listJAR(jf, jarRes, resources, exported);
    3.64 +        
    3.65 +        String cp = jf.getManifest().getMainAttributes().getValue("Class-Path"); // NOI18N
    3.66 +        String[] classpath = cp == null ? new String[0] : cp.split(" ");
    3.67 +
    3.68          if (c == null) {
    3.69              c = Bck2Brwsr.newCompiler();
    3.70          }
    3.71 @@ -91,11 +101,11 @@
    3.72              .addClasses(classes.toArray(new String[classes.size()]))
    3.73              .addExported(exported.toArray(new String[exported.size()]))
    3.74              .addResources(resources.toArray(new String[resources.size()]))
    3.75 -            .resources(new JarRes());
    3.76 +            .resources(jarRes);
    3.77      }
    3.78      
    3.79      private static void listJAR(
    3.80 -        JarFile j, List<String> classes,
    3.81 +        JarFile j, EmulationResources classes,
    3.82          List<String> resources, Set<String> keep
    3.83      ) throws IOException {
    3.84          Enumeration<JarEntry> en = j.entries();
    3.85 @@ -114,7 +124,7 @@
    3.86                  keep.add(pkg);
    3.87              }
    3.88              if (n.endsWith(".class")) {
    3.89 -                classes.add(n.substring(0, n.length() - 6));
    3.90 +                classes.addClassResource(n);
    3.91              } else {
    3.92                  resources.add(n);
    3.93                  if (n.startsWith("META-INF/services/") && keep != null) {
    3.94 @@ -142,11 +152,59 @@
    3.95              }
    3.96          }
    3.97      }
    3.98 +    
    3.99 +    static byte[] readFrom(InputStream is) throws IOException {
   3.100 +        int expLen = is.available();
   3.101 +        if (expLen < 1) {
   3.102 +            expLen = 1;
   3.103 +        }
   3.104 +        byte[] arr = new byte[expLen];
   3.105 +        int pos = 0;
   3.106 +        for (;;) {
   3.107 +            int read = is.read(arr, pos, arr.length - pos);
   3.108 +            if (read == -1) {
   3.109 +                break;
   3.110 +            }
   3.111 +            pos += read;
   3.112 +            if (pos == arr.length) {
   3.113 +                byte[] tmp = new byte[arr.length * 2];
   3.114 +                System.arraycopy(arr, 0, tmp, 0, arr.length);
   3.115 +                arr = tmp;
   3.116 +            }
   3.117 +        }
   3.118 +        if (pos != arr.length) {
   3.119 +            byte[] tmp = new byte[pos];
   3.120 +            System.arraycopy(arr, 0, tmp, 0, pos);
   3.121 +            arr = tmp;
   3.122 +        }
   3.123 +        return arr;
   3.124 +    }
   3.125 +    
   3.126  
   3.127      static class EmulationResources implements Bck2Brwsr.Resources {
   3.128 +        private final List<String> classes;
   3.129 +        private final Map<String,byte[]> converted = new HashMap<>();
   3.130 +        private final BytecodeProcessor proc;
   3.131 +
   3.132 +        protected EmulationResources(List<String> classes) {
   3.133 +            this.classes = classes;
   3.134 +            BytecodeProcessor p;
   3.135 +            try {
   3.136 +                Class<?> bpClass = Class.forName("org.apidesign.bck2brwsr.aot.RetroLambda");
   3.137 +                p = (BytecodeProcessor) bpClass.newInstance();
   3.138 +            } catch (Throwable t) {
   3.139 +                p = null;
   3.140 +            }
   3.141 +            this.proc = p;
   3.142 +        }
   3.143  
   3.144          @Override
   3.145          public InputStream get(String name) throws IOException {
   3.146 +            byte[] arr = converted.get(name);
   3.147 +            if (arr != null) {
   3.148 +                return new ByteArrayInputStream(arr);
   3.149 +            }
   3.150 +            
   3.151              Enumeration<URL> en = Bck2BrwsrJars.class.getClassLoader().getResources(name);
   3.152              URL u = null;
   3.153              while (en.hasMoreElements()) {
   3.154 @@ -162,6 +220,83 @@
   3.155              }
   3.156              return u.openStream();
   3.157          }
   3.158 +
   3.159 +        private void addClassResource(String n) throws IOException {
   3.160 +            if (proc != null) {
   3.161 +                try (InputStream is = this.get(n)) {
   3.162 +                    Map<String, byte[]> conv = proc.process(n, readFrom(is), this);
   3.163 +                    if (conv != null) {
   3.164 +                        boolean found = false;
   3.165 +                        for (Map.Entry<String, byte[]> entrySet : conv.entrySet()) {
   3.166 +                            String res = entrySet.getKey();
   3.167 +                            byte[] bytes = entrySet.getValue();
   3.168 +                            if (res.equals(n)) {
   3.169 +                                found = true;
   3.170 +                            }
   3.171 +                            assert res.endsWith(".class") : "Wrong resource: " + res;
   3.172 +                            converted.put(res, bytes);
   3.173 +                            classes.add(res.substring(0, res.length() - 6));
   3.174 +                        }
   3.175 +                        if (!found) {
   3.176 +                            throw new IOException("Cannot find " + n + " among " + conv);
   3.177 +                        }
   3.178 +                        return;
   3.179 +                    }
   3.180 +                }
   3.181 +            }
   3.182 +            classes.add(n.substring(0, n.length() - 6));
   3.183 +        }
   3.184 +    }
   3.185 +    
   3.186 +    private static Bck2Brwsr configureDir(Bck2Brwsr c, final File dir) throws IOException {
   3.187 +        List<String> arr = new ArrayList<>();
   3.188 +        List<String> classes = new ArrayList<>();
   3.189 +        class DirRes extends EmulationResources {
   3.190 +            public DirRes(List<String> classes) {
   3.191 +                super(classes);
   3.192 +            }
   3.193 +
   3.194 +            @Override
   3.195 +            public InputStream get(String name) throws IOException {
   3.196 +                InputStream is = super.get(name);
   3.197 +                if (is != null) {
   3.198 +                    return is;
   3.199 +                }
   3.200 +                File r = new File(dir, name.replace('/', File.separatorChar));
   3.201 +                if (r.exists()) {
   3.202 +                    return new FileInputStream(r);
   3.203 +                }
   3.204 +                return null;
   3.205 +            }
   3.206 +        }
   3.207 +        DirRes dirRes = new DirRes(classes);
   3.208 +        listDir(dir, null, dirRes, arr);
   3.209 +        if (c == null) {
   3.210 +            c = Bck2Brwsr.newCompiler();
   3.211 +        }
   3.212 +        return c
   3.213 +        .addRootClasses(classes.toArray(new String[0]))
   3.214 +        .addResources(arr.toArray(new String[0]))
   3.215 +        .library()
   3.216 +        //.obfuscation(ObfuscationLevel.FULL)
   3.217 +        .resources(dirRes);
   3.218 +    }
   3.219 +
   3.220 +    private static void listDir(
   3.221 +        File f, String pref, EmulationResources res, List<String> resources
   3.222 +    ) throws IOException {
   3.223 +        File[] arr = f.listFiles();
   3.224 +        if (arr == null) {
   3.225 +            if (f.getName().endsWith(".class")) {
   3.226 +                res.addClassResource(pref + f.getName());
   3.227 +            } else {
   3.228 +                resources.add(pref + f.getName());
   3.229 +            }
   3.230 +        } else {
   3.231 +            for (File ch : arr) {
   3.232 +                listDir(ch, pref == null ? "" : pref + f.getName() + "/", res, resources);
   3.233 +            }
   3.234 +        }
   3.235      }
   3.236      
   3.237  }
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/BytecodeProcessor.java	Sat Sep 13 18:33:05 2014 +0200
     4.3 @@ -0,0 +1,40 @@
     4.4 +/**
     4.5 + * Back 2 Browser Bytecode Translator
     4.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4.7 + *
     4.8 + * This program is free software: you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU General Public License as published by
    4.10 + * the Free Software Foundation, version 2 of the License.
    4.11 + *
    4.12 + * This program is distributed in the hope that it will be useful,
    4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.15 + * GNU General Public License for more details.
    4.16 + *
    4.17 + * You should have received a copy of the GNU General Public License
    4.18 + * along with this program. Look for COPYING file in the top folder.
    4.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    4.20 + */
    4.21 +package org.apidesign.bck2brwsr.aot;
    4.22 +
    4.23 +import java.io.IOException;
    4.24 +import java.util.Map;
    4.25 +import org.apidesign.vm4brwsr.Bck2Brwsr;
    4.26 +
    4.27 +/** Replace bytecode of a single class with many new bytecodes.
    4.28 + *
    4.29 + * @author Jaroslav Tulach
    4.30 + */
    4.31 +interface BytecodeProcessor {
    4.32 +    /** Does the conversion.
    4.33 +     * 
    4.34 +     * @param className the resource of the class to replace
    4.35 +     * @param byteCode the bytecode of the class
    4.36 +     * @param resources access to other resources in the system
    4.37 +     * @return map of resource to bytecode which must include at least 
    4.38 +     *   one element of name <code>className</code>
    4.39 +     * @throws IOException 
    4.40 +     */
    4.41 +    public Map<String,byte[]> process(String className, byte[] byteCode, Bck2Brwsr.Resources resources)
    4.42 +    throws IOException;
    4.43 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/RetroLambda.java	Sat Sep 13 18:33:05 2014 +0200
     5.3 @@ -0,0 +1,125 @@
     5.4 +/**
     5.5 + * Back 2 Browser Bytecode Translator
     5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5.7 + *
     5.8 + * This program is free software: you can redistribute it and/or modify
     5.9 + * it under the terms of the GNU General Public License as published by
    5.10 + * the Free Software Foundation, version 2 of the License.
    5.11 + *
    5.12 + * This program is distributed in the hope that it will be useful,
    5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.15 + * GNU General Public License for more details.
    5.16 + *
    5.17 + * You should have received a copy of the GNU General Public License
    5.18 + * along with this program. Look for COPYING file in the top folder.
    5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    5.20 + */
    5.21 +package org.apidesign.bck2brwsr.aot;
    5.22 +
    5.23 +import java.io.IOException;
    5.24 +import java.io.InputStream;
    5.25 +import java.util.Arrays;
    5.26 +import java.util.HashMap;
    5.27 +import java.util.Map;
    5.28 +import net.orfjackal.retrolambda.LambdaClassBackporter;
    5.29 +import net.orfjackal.retrolambda.LambdaClassDumper;
    5.30 +import net.orfjackal.retrolambda.LambdaClassSaver;
    5.31 +import net.orfjackal.retrolambda.LambdaReifier;
    5.32 +import net.orfjackal.retrolambda.LambdaUsageBackporter;
    5.33 +import net.orfjackal.retrolambda.asm.Opcodes;
    5.34 +import org.apidesign.bck2brwsr.core.ExtraJavaScript;
    5.35 +import org.apidesign.vm4brwsr.Bck2Brwsr;
    5.36 +
    5.37 +/**
    5.38 + *
    5.39 + * @author Jaroslav Tulach
    5.40 + */
    5.41 +@ExtraJavaScript(processByteCode = false, resource="")
    5.42 +final class RetroLambda extends LambdaClassSaver implements BytecodeProcessor {
    5.43 +    private Map<String,byte[]> converted;
    5.44 +    
    5.45 +    public RetroLambda() {
    5.46 +        super(null, Opcodes.V1_7);
    5.47 +    }
    5.48 +
    5.49 +    @Override
    5.50 +    public void saveIfLambda(String className, byte[] bytecode) {
    5.51 +        if (LambdaReifier.isLambdaClassToReify(className)) {
    5.52 +            try {
    5.53 +                byte[] backportedBytecode = LambdaClassBackporter.transform(bytecode, Opcodes.V1_7);
    5.54 +                putBytecode(className + ".class", backportedBytecode);
    5.55 +            } catch (Throwable t) {
    5.56 +                // print to stdout to keep in sync with other log output
    5.57 +                throw new IllegalStateException("ERROR: Failed to backport lambda class: " + className);
    5.58 +            }
    5.59 +        }
    5.60 +    }
    5.61 +
    5.62 +    private void putBytecode(String className, byte[] backportedBytecode) {
    5.63 +        assert className.endsWith(".class") : "Full resource: " + className;
    5.64 +        if (converted == null) {
    5.65 +            converted = new HashMap<>();
    5.66 +        }
    5.67 +        converted.put(className, backportedBytecode);
    5.68 +    }
    5.69 +    
    5.70 +    @Override
    5.71 +    public Map<String, byte[]> process(
    5.72 +        String className, byte[] byteCode, Bck2Brwsr.Resources resources
    5.73 +    ) throws IOException {
    5.74 +        int minor = byteCode[4] << 8 | byteCode[5];
    5.75 +        int major = byteCode[6] << 8 | byteCode[7];
    5.76 +        if (major <= 51) {
    5.77 +            return null;
    5.78 +        }
    5.79 +        
    5.80 +        ClassLoader prev = Thread.currentThread().getContextClassLoader();
    5.81 +        try (LambdaClassDumper dumper = new LambdaClassDumper(this)) {
    5.82 +            Thread.currentThread().setContextClassLoader(new ResLdr(resources));
    5.83 +            dumper.install();
    5.84 +            
    5.85 +            byte[] newB = LambdaUsageBackporter.transform(byteCode, Opcodes.V1_7);
    5.86 +            if (!Arrays.equals(newB, byteCode)) {
    5.87 +                putBytecode(className, newB);
    5.88 +            }
    5.89 +        } catch (Throwable t) {
    5.90 +            t.printStackTrace();
    5.91 +        } finally {
    5.92 +            Thread.currentThread().setContextClassLoader(prev);
    5.93 +        }
    5.94 +        
    5.95 +        Map<String, byte[]> ret = converted;
    5.96 +        converted = null;
    5.97 +        return ret;
    5.98 +    }
    5.99 +   
   5.100 +    private static final class ResLdr extends ClassLoader {
   5.101 +        private final Bck2Brwsr.Resources res;
   5.102 +
   5.103 +        public ResLdr(Bck2Brwsr.Resources res) {
   5.104 +            this.res = res;
   5.105 +        }
   5.106 +        
   5.107 +        @Override
   5.108 +        public Class<?> loadClass(String name) throws ClassNotFoundException {
   5.109 +            Class<?> c = findLoadedClass(name);
   5.110 +            if (c != null) {
   5.111 +                return c;
   5.112 +            }
   5.113 +            if (name.startsWith("java.")) {
   5.114 +                return super.loadClass(name);
   5.115 +            }
   5.116 +            String r = name.replace('.', '/') + ".class";
   5.117 +            try (InputStream is = res.get(r)) {
   5.118 +                if (is == null) {
   5.119 +                    throw new ClassNotFoundException(name);
   5.120 +                }
   5.121 +                byte[] arr = Bck2BrwsrJars.readFrom(is);
   5.122 +                return defineClass(name, arr, 0, arr.length);
   5.123 +            } catch (IOException e) {
   5.124 +                return super.loadClass(name);
   5.125 +            }
   5.126 +        }
   5.127 +    }    
   5.128 +}
     6.1 --- a/rt/emul/mini/src/main/java/java/lang/Class.java	Tue Sep 09 12:45:22 2014 +0200
     6.2 +++ b/rt/emul/mini/src/main/java/java/lang/Class.java	Sat Sep 13 18:33:05 2014 +0200
     6.3 @@ -94,6 +94,11 @@
     6.4      private static final int ENUM      = 0x00004000;
     6.5      private static final int SYNTHETIC = 0x00001000;
     6.6  
     6.7 +    /* Backing store of user-defined values pertaining to this class.
     6.8 +     * Maintained by the ClassValue class.
     6.9 +     */
    6.10 +    transient Object classValueMap;
    6.11 +    
    6.12      /*
    6.13       * Constructor. Only the Java Virtual Machine creates Class
    6.14       * objects.
     7.1 --- a/rt/emul/mini/src/main/java/java/lang/ClassLoader.java	Tue Sep 09 12:45:22 2014 +0200
     7.2 +++ b/rt/emul/mini/src/main/java/java/lang/ClassLoader.java	Sat Sep 13 18:33:05 2014 +0200
     7.3 @@ -499,13 +499,13 @@
     7.4       * @since  1.1
     7.5       */
     7.6      protected final Class<?> findLoadedClass(String name) {
     7.7 -        if (!checkName(name))
     7.8 +        try {
     7.9 +            return Class.forName(name);
    7.10 +        } catch (ClassNotFoundException ex) {
    7.11              return null;
    7.12 -        return findLoadedClass0(name);
    7.13 +        }
    7.14      }
    7.15  
    7.16 -    private native final Class findLoadedClass0(String name);
    7.17 -
    7.18      /**
    7.19       * Sets the signers of a class.  This should be invoked after defining a
    7.20       * class.  </p>
    7.21 @@ -884,10 +884,6 @@
    7.22          return false;
    7.23      }
    7.24  
    7.25 -    private boolean checkName(String name) {
    7.26 -        throw new UnsupportedOperationException(); 
    7.27 -    }
    7.28 -
    7.29      private Class findBootstrapClassOrNull(String name) {
    7.30          throw new UnsupportedOperationException();
    7.31      }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/rt/emul/mini/src/main/java/java/lang/NoSuchMethodError.java	Sat Sep 13 18:33:05 2014 +0200
     8.3 @@ -0,0 +1,60 @@
     8.4 +/*
     8.5 + * Copyright (c) 1994, 2008, 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;
    8.30 +
    8.31 +/**
    8.32 + * Thrown if an application tries to call a specified method of a
    8.33 + * class (either static or instance), and that class no longer has a
    8.34 + * definition of that method.
    8.35 + * <p>
    8.36 + * Normally, this error is caught by the compiler; this error can
    8.37 + * only occur at run time if the definition of a class has
    8.38 + * incompatibly changed.
    8.39 + *
    8.40 + * @author  unascribed
    8.41 + * @since   JDK1.0
    8.42 + */
    8.43 +public
    8.44 +class NoSuchMethodError extends IncompatibleClassChangeError {
    8.45 +    private static final long serialVersionUID = -3765521442372831335L;
    8.46 +
    8.47 +    /**
    8.48 +     * Constructs a <code>NoSuchMethodError</code> with no detail message.
    8.49 +     */
    8.50 +    public NoSuchMethodError() {
    8.51 +        super();
    8.52 +    }
    8.53 +
    8.54 +    /**
    8.55 +     * Constructs a <code>NoSuchMethodError</code> with the
    8.56 +     * specified detail message.
    8.57 +     *
    8.58 +     * @param   s   the detail message.
    8.59 +     */
    8.60 +    public NoSuchMethodError(String s) {
    8.61 +        super(s);
    8.62 +    }
    8.63 +}
     9.1 --- a/rt/emul/mini/src/main/java/java/lang/VirtualMachineError.java	Tue Sep 09 12:45:22 2014 +0200
     9.2 +++ b/rt/emul/mini/src/main/java/java/lang/VirtualMachineError.java	Sat Sep 13 18:33:05 2014 +0200
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -33,8 +33,9 @@
    9.11   * @author  Frank Yellin
    9.12   * @since   JDK1.0
    9.13   */
    9.14 -abstract public
    9.15 -class VirtualMachineError extends Error {
    9.16 +abstract public class VirtualMachineError extends Error {
    9.17 +    private static final long serialVersionUID = 4161983926571568670L;
    9.18 +
    9.19      /**
    9.20       * Constructs a <code>VirtualMachineError</code> with no detail message.
    9.21       */
    9.22 @@ -46,9 +47,43 @@
    9.23       * Constructs a <code>VirtualMachineError</code> with the specified
    9.24       * detail message.
    9.25       *
    9.26 -     * @param   s   the detail message.
    9.27 +     * @param   message   the detail message.
    9.28       */
    9.29 -    public VirtualMachineError(String s) {
    9.30 -        super(s);
    9.31 +    public VirtualMachineError(String message) {
    9.32 +        super(message);
    9.33 +    }
    9.34 +
    9.35 +    /**
    9.36 +     * Constructs a {@code VirtualMachineError} with the specified
    9.37 +     * detail message and cause.  <p>Note that the detail message
    9.38 +     * associated with {@code cause} is <i>not</i> automatically
    9.39 +     * incorporated in this error's detail message.
    9.40 +     *
    9.41 +     * @param  message the detail message (which is saved for later retrieval
    9.42 +     *         by the {@link #getMessage()} method).
    9.43 +     * @param  cause the cause (which is saved for later retrieval by the
    9.44 +     *         {@link #getCause()} method).  (A {@code null} value is
    9.45 +     *         permitted, and indicates that the cause is nonexistent or
    9.46 +     *         unknown.)
    9.47 +     * @since  1.8
    9.48 +     */
    9.49 +    public VirtualMachineError(String message, Throwable cause) {
    9.50 +        super(message, cause);
    9.51 +    }
    9.52 +
    9.53 +    /**
    9.54 +     * Constructs an a {@code VirtualMachineError} with the specified
    9.55 +     * cause and a detail message of {@code (cause==null ? null :
    9.56 +     * cause.toString())} (which typically contains the class and
    9.57 +     * detail message of {@code cause}).
    9.58 +     *
    9.59 +     * @param  cause the cause (which is saved for later retrieval by the
    9.60 +     *         {@link #getCause()} method).  (A {@code null} value is
    9.61 +     *         permitted, and indicates that the cause is nonexistent or
    9.62 +     *         unknown.)
    9.63 +     * @since  1.8
    9.64 +     */
    9.65 +    public VirtualMachineError(Throwable cause) {
    9.66 +        super(cause);
    9.67      }
    9.68  }
    10.1 --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Tue Sep 09 12:45:22 2014 +0200
    10.2 +++ b/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Sat Sep 13 18:33:05 2014 +0200
    10.3 @@ -53,7 +53,7 @@
    10.4          + "var arr = new Array();\n"
    10.5          + "function check(m, verify) {\n"
    10.6          + "  if (m.indexOf(prefix) === 0) {\n"
    10.7 -        + "     if (!c[m].cls) return;\n"
    10.8 +        + "     if (!c[m] || !c[m].cls) return;\n"
    10.9          + "     if (verify) {\n"
   10.10          + "       for (var i = 0; i < arr.length; i += 3) {\n"
   10.11          + "         if (arr[i] === m) return;\n"
    11.1 --- a/rt/pom.xml	Tue Sep 09 12:45:22 2014 +0200
    11.2 +++ b/rt/pom.xml	Sat Sep 13 18:33:05 2014 +0200
    11.3 @@ -19,4 +19,14 @@
    11.4      <module>vmtest</module>
    11.5      <module>aot</module>
    11.6    </modules>
    11.7 +  <profiles>
    11.8 +      <profile>
    11.9 +          <activation>
   11.10 +              <jdk>1.8</jdk>
   11.11 +          </activation>
   11.12 +          <modules>
   11.13 +              <module>vm8</module>
   11.14 +          </modules>
   11.15 +      </profile>
   11.16 +  </profiles>
   11.17  </project>
    12.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java	Tue Sep 09 12:45:22 2014 +0200
    12.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java	Sat Sep 13 18:33:05 2014 +0200
    12.3 @@ -28,6 +28,7 @@
    12.4  import java.io.DataInputStream;
    12.5  import java.io.IOException;
    12.6  import java.io.InputStream;
    12.7 +import java.util.Arrays;
    12.8  import org.apidesign.bck2brwsr.core.JavaScriptBody;
    12.9  import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
   12.10  
   12.11 @@ -58,6 +59,9 @@
   12.12      public static final int CONSTANT_METHOD              = 10;
   12.13      public static final int CONSTANT_INTERFACEMETHOD     = 11;
   12.14      public static final int CONSTANT_NAMEANDTYPE         = 12;
   12.15 +    public static final int CONSTANT_METHODHANDLE     = 15;
   12.16 +    public static final int CONSTANT_METHODTYPE     = 16;
   12.17 +    public static final int CONSTANT_INVOKEDYNAMIC     = 18;
   12.18  
   12.19      /* Access Flags */
   12.20      public static final int ACC_PUBLIC                   = 0x00000001;
   12.21 @@ -287,7 +291,7 @@
   12.22      public static final int opc_invokespecial            = 183;
   12.23      public static final int opc_invokestatic             = 184;
   12.24      public static final int opc_invokeinterface          = 185;
   12.25 -//    public static final int opc_xxxunusedxxx             = 186;
   12.26 +    public static final int opc_invokedynamic            = 186;
   12.27      public static final int opc_new                      = 187;
   12.28      public static final int opc_newarray                 = 188;
   12.29      public static final int opc_anewarray                = 189;
   12.30 @@ -495,7 +499,7 @@
   12.31       */
   12.32      private static class CPX {
   12.33  
   12.34 -        int cpx;
   12.35 +        final int cpx;
   12.36  
   12.37          CPX(int cpx) {
   12.38              this.cpx = cpx;
   12.39 @@ -507,9 +511,9 @@
   12.40       *
   12.41       * @author Sucheta Dambalkar (Adopted code from jdis)
   12.42       */
   12.43 -    private static class CPX2 {
   12.44 +    static class CPX2 {
   12.45  
   12.46 -        int cpx1, cpx2;
   12.47 +        final int cpx1, cpx2;
   12.48  
   12.49          CPX2(int cpx1, int cpx2) {
   12.50              this.cpx1 = cpx1;
   12.51 @@ -538,6 +542,7 @@
   12.52          private FieldData[] fields;
   12.53          private MethodData[] methods;
   12.54          private InnerClassData[] innerClasses;
   12.55 +        private BootMethodData[] bootMethods;
   12.56          private int attributes_count;
   12.57          private AttrData[] attrs;
   12.58          private int source_cpx = 0;
   12.59 @@ -621,6 +626,12 @@
   12.60                      AttrData attr = new AttrData(this);
   12.61                      attr.read(name_cpx);
   12.62                      attrs[k] = attr;
   12.63 +                } else if (getTag(name_cpx) == CONSTANT_UTF8
   12.64 +                    && getString(name_cpx).equals("BootstrapMethods")) {
   12.65 +                    AttrData attr = new AttrData(this);
   12.66 +                    bootMethods = readBootstrapMethods(in);
   12.67 +                    attr.read(name_cpx);
   12.68 +                    attrs[k] = attr;
   12.69                  } else {
   12.70                      AttrData attr = new AttrData(this);
   12.71                      attr.read(name_cpx, in);
   12.72 @@ -630,6 +641,22 @@
   12.73              in.close();
   12.74          } // end ClassData.read()
   12.75  
   12.76 +        BootMethodData[] readBootstrapMethods(DataInputStream in) throws IOException {
   12.77 +            int attr_len = in.readInt();  //attr_lengt
   12.78 +            int number = in.readShort();
   12.79 +            BootMethodData[] arr = new BootMethodData[number];
   12.80 +            for (int i = 0; i < number; i++) {
   12.81 +                int ref = in.readShort();
   12.82 +                int len = in.readShort();
   12.83 +                int[] args = new int[len];
   12.84 +                for (int j = 0; j < len; j++) {
   12.85 +                    args[j] = in.readShort();
   12.86 +                }
   12.87 +                arr[i] = new BootMethodData(this, ref, args);
   12.88 +            }
   12.89 +            return arr;
   12.90 +        }
   12.91 +        
   12.92          /**
   12.93           * Reads and stores constant pool info.
   12.94           */
   12.95 @@ -668,7 +695,15 @@
   12.96                      case CONSTANT_NAMEANDTYPE:
   12.97                          cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
   12.98                          break;
   12.99 -
  12.100 +                    case CONSTANT_METHODHANDLE:
  12.101 +                        cpool[i] = new CPX2(in.readByte(), in.readUnsignedShort());
  12.102 +                        break;
  12.103 +                    case CONSTANT_METHODTYPE:
  12.104 +                        cpool[i] = new CPX(in.readUnsignedShort());
  12.105 +                        break;
  12.106 +                    case CONSTANT_INVOKEDYNAMIC:
  12.107 +                        cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
  12.108 +                        break;
  12.109                      case 0:
  12.110                      default:
  12.111                          throw new ClassFormatError("invalid constant type: " + (int) tags[i]);
  12.112 @@ -1107,8 +1142,12 @@
  12.113  
  12.114                  case CONSTANT_NAMEANDTYPE:
  12.115                      return getName(((CPX2) x).cpx1) + ":" + StringValue(((CPX2) x).cpx2);
  12.116 +                case CONSTANT_METHODHANDLE:
  12.117 +                    return "K" + ((CPX2)x).cpx1 + "@" + stringValue(((CPX2)x).cpx2, textual);
  12.118 +                case CONSTANT_METHODTYPE:
  12.119 +                    return stringValue(((CPX)x).cpx, true);
  12.120                  default:
  12.121 -                    return "UnknownTag"; //TBD
  12.122 +                    return "UnknownTag" + tag; //TBD
  12.123              }
  12.124          }
  12.125  
  12.126 @@ -1191,6 +1230,10 @@
  12.127                  return null;
  12.128              }
  12.129          }
  12.130 +        
  12.131 +        public BootMethodData getBootMethod(int indx) {
  12.132 +            return bootMethods != null ? bootMethods[indx] : null;
  12.133 +        }
  12.134  
  12.135          /**
  12.136           * Returns total constant pool entry count.
  12.137 @@ -1549,6 +1592,31 @@
  12.138              return accflags;
  12.139          }
  12.140      } // end InnerClassData
  12.141 +    
  12.142 +    static class BootMethodData {
  12.143 +        private final ClassData clazz;
  12.144 +        final int method;
  12.145 +        private final int[] args;
  12.146 +
  12.147 +        private BootMethodData(ClassData clazz, int method, int[] args) {
  12.148 +            this.clazz = clazz;
  12.149 +            this.method = method;
  12.150 +            this.args = args;
  12.151 +        }
  12.152 +
  12.153 +        @Override
  12.154 +        public String toString() {
  12.155 +            StringBuilder sb = new StringBuilder();
  12.156 +            sb.append(clazz.stringValue(method, true));
  12.157 +            sb.append('(');
  12.158 +            for (int indx : args) {
  12.159 +                sb.append("\n  ");
  12.160 +                sb.append(clazz.stringValue(indx, true));
  12.161 +            }
  12.162 +            sb.append(')');
  12.163 +            return sb.toString();
  12.164 +        }
  12.165 +    }
  12.166  
  12.167      /**
  12.168       * Strores LineNumberTable data information.
  12.169 @@ -1800,7 +1868,7 @@
  12.170                  stackMap[i] = new StackMapData(in, this);
  12.171              }
  12.172          }
  12.173 -
  12.174 +        
  12.175          /**
  12.176           * Return access of the method.
  12.177           */
    13.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Sep 09 12:45:22 2014 +0200
    13.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Sep 13 18:33:05 2014 +0200
    13.3 @@ -19,7 +19,7 @@
    13.4  
    13.5  import java.io.IOException;
    13.6  import java.io.InputStream;
    13.7 -import java.util.Locale;
    13.8 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    13.9  import static org.apidesign.vm4brwsr.ByteCodeParser.*;
   13.10  
   13.11  /** Translator of the code inside class files to JavaScript.
   13.12 @@ -258,9 +258,22 @@
   13.13              append("\n    ").append(destObject).append(".").append(mn).append(".cls = CLS;");
   13.14          }
   13.15          append("\n    c.constructor = CLS;");
   13.16 -        append("\n    function fillInstOf(x) {");
   13.17 +        append("\n    function ").append(className).append("fillInstOf(x) {");
   13.18          String instOfName = "$instOf_" + className;
   13.19          append("\n        Object.defineProperty(x, '").append(instOfName).append("', { value : true });");
   13.20 +        if (jc.isInterface()) {
   13.21 +            for (MethodData m : jc.getMethods()) {
   13.22 +                if ((m.getAccess() & ACC_ABSTRACT) == 0
   13.23 +                        && (m.getAccess() & ACC_STATIC) == 0
   13.24 +                        && (m.getAccess() & ACC_PRIVATE) == 0) {
   13.25 +                    final String mn = findMethodName(m, new StringBuilder());
   13.26 +                    append("\n        try {");
   13.27 +                    append("\n          if (!x['").append(mn).append("']) Object.defineProperty(x, '").append(mn).append("', { value : c['").append(mn).append("']});");
   13.28 +                    append("\n        } catch (ignore) {");
   13.29 +                    append("\n        }");
   13.30 +                }
   13.31 +            }
   13.32 +        }
   13.33          for (String superInterface : jc.getSuperInterfaces()) {
   13.34              String intrfc = superInterface.replace('/', '_');
   13.35              append("\n      vm.").append(intrfc).append("(false)['fillInstOf'](x);");
   13.36 @@ -268,8 +281,8 @@
   13.37          }
   13.38          append("\n    }");
   13.39          append("\n    try {");
   13.40 -        append("\n      Object.defineProperty(c, 'fillInstOf', { value: fillInstOf });");
   13.41 -        append("\n      fillInstOf(c);");
   13.42 +        append("\n      Object.defineProperty(c, 'fillInstOf', { value: ").append(className).append("fillInstOf });");
   13.43 +        append("\n      ").append(className).append("fillInstOf(c);");
   13.44          append("\n    } catch (ignore) {");
   13.45          append("\n    }");
   13.46  //        obfuscationDelegate.exportJSProperty(this, "c", instOfName);
   13.47 @@ -1051,6 +1064,49 @@
   13.48                  case opc_invokestatic:
   13.49                      i = invokeStaticMethod(byteCodes, i, smapper, true);
   13.50                      break;
   13.51 +                case opc_invokedynamic: {
   13.52 +                    int indx = readUShortArg(byteCodes, i);
   13.53 +                    println("invoke dynamic: " + indx);
   13.54 +                    ByteCodeParser.CPX2 c2 = jc.getCpoolEntry(indx);
   13.55 +                    BootMethodData bm = jc.getBootMethod(c2.cpx1);
   13.56 +                    CPX2 methodHandle = jc.getCpoolEntry(bm.method);
   13.57 +                    println("  type: " + methodHandle.cpx1);
   13.58 +                    String[] mi = jc.getFieldInfoName(methodHandle.cpx2);
   13.59 +                    String mcn = mangleClassName(mi[0]);
   13.60 +                    char[] returnType = {'V'};
   13.61 +                    StringBuilder cnt = new StringBuilder();
   13.62 +                    String mn = findMethodName(mi, cnt, returnType);
   13.63 +                    println("  mi[0]: " + mi[0]);
   13.64 +                    println("  mi[1]: " + mi[1]);
   13.65 +                    println("  mi[2]: " + mi[2]);
   13.66 +                    println("  mn   : " + mn);
   13.67 +                    println("  name and type: " + jc.stringValue(c2.cpx2, true));
   13.68 +                    CPX2 nameAndType = jc.getCpoolEntry(c2.cpx2);
   13.69 +                    String type = jc.StringValue(nameAndType.cpx2);
   13.70 +                    String object = accessClass(mcn) + "(false)";
   13.71 +                    if (mn.startsWith("cons_")) {
   13.72 +                        object += ".constructor";
   13.73 +                    }
   13.74 +                    append("var metHan = ");
   13.75 +                    append(accessStaticMethod(object, mn, mi));
   13.76 +                    append('(');
   13.77 +                    String lookup = accessClass("java_lang_invoke_MethodHandles") + "(false).findFor__Ljava_lang_invoke_MethodHandles$Lookup_2Ljava_lang_Class_2(CLS.$class)";
   13.78 +                    append(lookup);
   13.79 +                    append(", '").append(mi[1]).append("', ");
   13.80 +                    String methodType = accessClass("java_lang_invoke_MethodType") + "(false).fromMethodDescriptorString__Ljava_lang_invoke_MethodType_2Ljava_lang_String_2Ljava_lang_ClassLoader_2(";
   13.81 +                    append(methodType).append("'").append(type).append("', null)");
   13.82 +//                    if (numArguments > 0) {
   13.83 +//                        append(vars[0]);
   13.84 +//                        for (int j = 1; j < numArguments; ++j) {
   13.85 +//                            append(", ");
   13.86 +//                            append(vars[j]);
   13.87 +//                        }
   13.88 +//                    }
   13.89 +                    append(");");
   13.90 +                    emit(smapper, this, "throw 'Invoke dynamic: ' + @1 + ': ' + metHan;", "" + indx);
   13.91 +                    i += 4;
   13.92 +                    break;
   13.93 +                }
   13.94                  case opc_new: {
   13.95                      int indx = readUShortArg(byteCodes, i);
   13.96                      String ci = jc.getClassName(indx);
   13.97 @@ -1557,7 +1613,7 @@
   13.98                          sb.append(ch);
   13.99                      } else {
  13.100                          sb.append("_0");
  13.101 -                        String hex = Integer.toHexString(ch).toLowerCase(Locale.ENGLISH);
  13.102 +                        String hex = Integer.toHexString(ch).toLowerCase();
  13.103                          for (int m = hex.length(); m < 4; m++) {
  13.104                              sb.append("0");
  13.105                          }
  13.106 @@ -2310,4 +2366,9 @@
  13.107              append(Integer.toString(cc));
  13.108          }
  13.109      }
  13.110 +    
  13.111 +    @JavaScriptBody(args = "msg", body = "")
  13.112 +    private static void println(String msg) {
  13.113 +        System.err.println(msg);
  13.114 +    }
  13.115  }
    14.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Tue Sep 09 12:45:22 2014 +0200
    14.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Sat Sep 13 18:33:05 2014 +0200
    14.3 @@ -123,10 +123,18 @@
    14.4      }
    14.5  
    14.6      static TestVM compileClass(StringBuilder sb, ScriptEngine[] eng, String... names) throws ScriptException, IOException {
    14.7 +        return compileClass(sb, eng, new EmulationResources(), names);
    14.8 +    }
    14.9 +    static TestVM compileClass(
   14.10 +        StringBuilder sb, 
   14.11 +        ScriptEngine[] eng, 
   14.12 +        Bck2Brwsr.Resources resources, 
   14.13 +        String... names
   14.14 +    ) throws ScriptException, IOException {
   14.15          if (sb == null) {
   14.16              sb = new StringBuilder();
   14.17          }
   14.18 -        Bck2Brwsr.generate(sb, new EmulationResources(), names);
   14.19 +        Bck2Brwsr.generate(sb, resources, names);
   14.20          ScriptEngineManager sem = new ScriptEngineManager();
   14.21          ScriptEngine js = sem.getEngineByExtension("js");
   14.22          if (eng != null) {
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/rt/vm8/pom.xml	Sat Sep 13 18:33:05 2014 +0200
    15.3 @@ -0,0 +1,74 @@
    15.4 +<?xml version="1.0" encoding="UTF-8"?>
    15.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    15.6 +    <modelVersion>4.0.0</modelVersion>
    15.7 +    <parent>
    15.8 +        <groupId>org.apidesign.bck2brwsr</groupId>
    15.9 +        <artifactId>rt</artifactId>
   15.10 +        <version>1.0-SNAPSHOT</version>
   15.11 +    </parent>
   15.12 +    <artifactId>vm8</artifactId>
   15.13 +    <name>Bck2Brwsr on JDK8</name>
   15.14 +    <packaging>jar</packaging>
   15.15 +    <build>
   15.16 +        <plugins>
   15.17 +            <plugin>
   15.18 +                <groupId>org.apache.maven.plugins</groupId>
   15.19 +                <artifactId>maven-compiler-plugin</artifactId>
   15.20 +                <version>2.3.2</version>
   15.21 +                <configuration>
   15.22 +                    <source>1.8</source>
   15.23 +                    <target>1.8</target>
   15.24 +                </configuration>
   15.25 +            </plugin>
   15.26 +            <plugin>
   15.27 +                <groupId>org.apache.maven.plugins</groupId>
   15.28 +                <artifactId>maven-surefire-plugin</artifactId>
   15.29 +                <configuration>
   15.30 +                    <systemProperties>
   15.31 +                        <vmtest.js>brwsr</vmtest.js>
   15.32 +                    </systemProperties>
   15.33 +                </configuration>
   15.34 +            </plugin>
   15.35 +        </plugins>
   15.36 +    </build>
   15.37 +    <dependencies>
   15.38 +        <dependency>
   15.39 +            <groupId>org.testng</groupId>
   15.40 +            <artifactId>testng</artifactId>
   15.41 +            <scope>test</scope>
   15.42 +        </dependency>
   15.43 +        <dependency>
   15.44 +            <groupId>org.apidesign.bck2brwsr</groupId>
   15.45 +            <artifactId>vm4brwsr</artifactId>
   15.46 +            <version>${project.version}</version>
   15.47 +            <scope>test</scope>
   15.48 +            <type>jar</type>
   15.49 +        </dependency>
   15.50 +        <dependency>
   15.51 +            <groupId>org.ow2.asm</groupId>
   15.52 +            <artifactId>asm-debug-all</artifactId>
   15.53 +            <version>4.1</version>
   15.54 +            <scope>test</scope>
   15.55 +            <type>jar</type>
   15.56 +        </dependency>
   15.57 +        <dependency>
   15.58 +            <groupId>${project.groupId}</groupId>
   15.59 +            <artifactId>emul</artifactId>
   15.60 +            <version>${project.version}</version>
   15.61 +            <scope>test</scope>
   15.62 +        </dependency>
   15.63 +        <dependency>
   15.64 +            <groupId>org.apidesign.bck2brwsr</groupId>
   15.65 +            <artifactId>vmtest</artifactId>
   15.66 +            <version>${project.version}</version>
   15.67 +            <scope>test</scope>
   15.68 +            <type>jar</type>
   15.69 +        </dependency>
   15.70 +        <dependency>
   15.71 +            <groupId>${project.groupId}</groupId>
   15.72 +            <artifactId>launcher.http</artifactId>
   15.73 +            <version>${project.version}</version>
   15.74 +            <scope>test</scope>
   15.75 +        </dependency>
   15.76 +    </dependencies>
   15.77 +</project>
   15.78 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/Defaults.java	Sat Sep 13 18:33:05 2014 +0200
    16.3 @@ -0,0 +1,65 @@
    16.4 +/**
    16.5 + * Back 2 Browser Bytecode Translator
    16.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    16.7 + *
    16.8 + * This program is free software: you can redistribute it and/or modify
    16.9 + * it under the terms of the GNU General Public License as published by
   16.10 + * the Free Software Foundation, version 2 of the License.
   16.11 + *
   16.12 + * This program is distributed in the hope that it will be useful,
   16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 + * GNU General Public License for more details.
   16.16 + *
   16.17 + * You should have received a copy of the GNU General Public License
   16.18 + * along with this program. Look for COPYING file in the top folder.
   16.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   16.20 + */
   16.21 +package org.apidesign.bck2brwsr.vm8;
   16.22 +
   16.23 +public interface Defaults {
   16.24 +    public static int staticValue() {
   16.25 +        return 42;
   16.26 +    }
   16.27 +    
   16.28 +    public default int value() {
   16.29 +        return 42;
   16.30 +    }
   16.31 +    
   16.32 +    public static Defaults create(int type) {
   16.33 +        class X implements Defaults {
   16.34 +        }
   16.35 +        class Y implements Defaults {
   16.36 +            @Override
   16.37 +            public int value() {
   16.38 +                return 7;
   16.39 +            }
   16.40 +        }
   16.41 +        class Z implements DoubleDefaults {
   16.42 +        }
   16.43 +        switch (type) {
   16.44 +            case 0: return new X();
   16.45 +            case 1: return new Y();
   16.46 +            default: return new Z();
   16.47 +        }
   16.48 +    }
   16.49 +    
   16.50 +    public static int defaultValue() {
   16.51 +        return create(0).value();
   16.52 +    }
   16.53 +    
   16.54 +    public static int myValue() {
   16.55 +        return create(1).value();
   16.56 +    }
   16.57 +
   16.58 +    public static int sndValue() {
   16.59 +        return create(2).value();
   16.60 +    }
   16.61 +    
   16.62 +    public interface DoubleDefaults extends Defaults {
   16.63 +        @Override
   16.64 +        public default int value() {
   16.65 +            return 84;
   16.66 +        }
   16.67 +    }
   16.68 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/DefaultsTest.java	Sat Sep 13 18:33:05 2014 +0200
    17.3 @@ -0,0 +1,41 @@
    17.4 +/**
    17.5 + * Back 2 Browser Bytecode Translator
    17.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    17.7 + *
    17.8 + * This program is free software: you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU General Public License as published by
   17.10 + * the Free Software Foundation, version 2 of the License.
   17.11 + *
   17.12 + * This program is distributed in the hope that it will be useful,
   17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 + * GNU General Public License for more details.
   17.16 + *
   17.17 + * You should have received a copy of the GNU General Public License
   17.18 + * along with this program. Look for COPYING file in the top folder.
   17.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   17.20 + */
   17.21 +package org.apidesign.bck2brwsr.vm8;
   17.22 +
   17.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   17.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   17.25 +import org.testng.annotations.Factory;
   17.26 +
   17.27 +public class DefaultsTest {
   17.28 +    @Compare public int callStatic() throws Exception {
   17.29 +        return Defaults.defaultValue();
   17.30 +    }
   17.31 +
   17.32 +    @Compare public int overridenValue() throws Exception {
   17.33 +        return Defaults.myValue();
   17.34 +    }
   17.35 +    
   17.36 +    @Compare public int doubleDefault() throws Exception {
   17.37 +        return Defaults.sndValue();
   17.38 +    }
   17.39 +
   17.40 +    @Factory public static Object[] create() {
   17.41 +        return VMTest.create(DefaultsTest.class);
   17.42 +    }
   17.43 +    
   17.44 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/Lambdas.java	Sat Sep 13 18:33:05 2014 +0200
    18.3 @@ -0,0 +1,36 @@
    18.4 +/**
    18.5 + * Back 2 Browser Bytecode Translator
    18.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18.7 + *
    18.8 + * This program is free software: you can redistribute it and/or modify
    18.9 + * it under the terms of the GNU General Public License as published by
   18.10 + * the Free Software Foundation, version 2 of the License.
   18.11 + *
   18.12 + * This program is distributed in the hope that it will be useful,
   18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.15 + * GNU General Public License for more details.
   18.16 + *
   18.17 + * You should have received a copy of the GNU General Public License
   18.18 + * along with this program. Look for COPYING file in the top folder.
   18.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   18.20 + */
   18.21 +package org.apidesign.bck2brwsr.vm8;
   18.22 +
   18.23 +/**
   18.24 + *
   18.25 + * @author Jaroslav Tulach
   18.26 + */
   18.27 +public class Lambdas {
   18.28 +    private static void fewTimes(Runnable r, int cnt) {
   18.29 +        while (cnt-- > 0) {
   18.30 +            r.run();
   18.31 +        }
   18.32 +    }
   18.33 +    
   18.34 +    public static String compound() {
   18.35 +        StringBuilder sb = new StringBuilder();
   18.36 +        fewTimes(() -> sb.append('X'), 10);
   18.37 +        return sb.toString();
   18.38 +    }
   18.39 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/LambdasTest.java	Sat Sep 13 18:33:05 2014 +0200
    19.3 @@ -0,0 +1,37 @@
    19.4 +/**
    19.5 + * Back 2 Browser Bytecode Translator
    19.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    19.7 + *
    19.8 + * This program is free software: you can redistribute it and/or modify
    19.9 + * it under the terms of the GNU General Public License as published by
   19.10 + * the Free Software Foundation, version 2 of the License.
   19.11 + *
   19.12 + * This program is distributed in the hope that it will be useful,
   19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.15 + * GNU General Public License for more details.
   19.16 + *
   19.17 + * You should have received a copy of the GNU General Public License
   19.18 + * along with this program. Look for COPYING file in the top folder.
   19.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   19.20 + */
   19.21 +package org.apidesign.bck2brwsr.vm8;
   19.22 +
   19.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   19.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   19.25 +import org.testng.annotations.Factory;
   19.26 +
   19.27 +/**
   19.28 + *
   19.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   19.30 + */
   19.31 +public class LambdasTest {
   19.32 +    @Compare public String StringverifyJSTime() throws Exception {
   19.33 +        return Lambdas.compound();
   19.34 +    }
   19.35 +    
   19.36 +    @Factory public static Object[] create() {
   19.37 +        return VMTest.create(LambdasTest.class);
   19.38 +    }
   19.39 +}
   19.40 +