vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 07 Dec 2012 06:29:54 +0100
branchlazyvm
changeset 277 e4b9eee9be83
parent 248 vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java@0bfcb6585290
child 278 ad49b48b7919
permissions -rw-r--r--
Lazy loading is now part of GenJS
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import java.io.ByteArrayInputStream;
    21 import java.io.IOException;
    22 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    23 
    24 /**
    25  *
    26  * @author Jaroslav Tulach <jtulach@netbeans.org>
    27  */
    28 class VMLazy extends ByteCodeToJavaScript {
    29     private final Object loader;
    30     
    31     private VMLazy(Object loader, Appendable out) {
    32         super(out);
    33         this.loader = loader;
    34     }
    35     
    36     static void init() {
    37     }
    38     
    39     @JavaScriptBody(args={"res", "args" }, body = "return args[0](res.toString());")
    40     private static native byte[] read(String res, Object[] args);
    41     
    42     static Object load(Object loader, String name, Object[] arguments) 
    43     throws IOException, ClassNotFoundException {
    44         String res = name.replace('.', '/') + ".class";
    45         byte[] arr = read(res, arguments);
    46         if (arr == null) {
    47             throw new ClassNotFoundException(name);
    48         }
    49         String code = toJavaScript(loader, arr);
    50         return applyCode(loader, name, code);
    51     }
    52     
    53     @JavaScriptBody(args = {"loader", "name", "script" }, body =
    54         "try {\n" +
    55         "  new Function(script)(loader, name);\n" +
    56         "} catch (ex) {\n" +
    57         "  throw 'Cannot compile ' + ex + ' script:\\\\n' + script;\n" +
    58         "}\n" +
    59         "return vm[name](false);\n"
    60     )
    61     private static native Object applyCode(Object loader, String name, String script);
    62     
    63     private static String toJavaScript(Object loader, byte[] is) throws IOException {
    64         StringBuilder sb = new StringBuilder();
    65         sb.append("var loader = arguments[0];\n");
    66         sb.append("var vm = loader.vm;\n");
    67         new VMLazy(loader, sb).compile(new ByteArrayInputStream(is));
    68         return sb.toString().toString();
    69     }
    70 
    71     @JavaScriptBody(args = { "self", "n" }, 
    72         body=
    73           "var cls = n.replace__Ljava_lang_String_2CC(n,'/','_').toString();"
    74         + "var loader = self.fld_loader;"
    75         + "var vm = loader.vm;"
    76         + "if (vm[cls]) return false;"
    77         + "vm[cls] = function() {"
    78         + "  return loader.loadClass(n,cls);"
    79         + "};"
    80         + "return true;"
    81     )
    82     @Override
    83     protected boolean requireReference(String internalClassName) {
    84         throw new UnsupportedOperationException();
    85     }
    86 
    87     @Override
    88     protected void requireScript(String resourcePath) {
    89     }
    90 
    91     @Override
    92     String assignClass(String className) {
    93         return "vm[arguments[1]]=";
    94     }
    95 
    96     @Override
    97     String accessClass(String classOperation) {
    98         return "vm." + classOperation;
    99     }
   100 }