1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Dec 07 06:29:54 2012 +0100
1.3 @@ -0,0 +1,100 @@
1.4 +/**
1.5 + * Back 2 Browser Bytecode Translator
1.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, version 2 of the License.
1.11 + *
1.12 + * This program is distributed in the hope that it will be useful,
1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 + * GNU General Public License for more details.
1.16 + *
1.17 + * You should have received a copy of the GNU General Public License
1.18 + * along with this program. Look for COPYING file in the top folder.
1.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
1.20 + */
1.21 +package org.apidesign.vm4brwsr;
1.22 +
1.23 +import java.io.ByteArrayInputStream;
1.24 +import java.io.IOException;
1.25 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.26 +
1.27 +/**
1.28 + *
1.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.30 + */
1.31 +class VMLazy extends ByteCodeToJavaScript {
1.32 + private final Object loader;
1.33 +
1.34 + private VMLazy(Object loader, Appendable out) {
1.35 + super(out);
1.36 + this.loader = loader;
1.37 + }
1.38 +
1.39 + static void init() {
1.40 + }
1.41 +
1.42 + @JavaScriptBody(args={"res", "args" }, body = "return args[0](res.toString());")
1.43 + private static native byte[] read(String res, Object[] args);
1.44 +
1.45 + static Object load(Object loader, String name, Object[] arguments)
1.46 + throws IOException, ClassNotFoundException {
1.47 + String res = name.replace('.', '/') + ".class";
1.48 + byte[] arr = read(res, arguments);
1.49 + if (arr == null) {
1.50 + throw new ClassNotFoundException(name);
1.51 + }
1.52 + String code = toJavaScript(loader, arr);
1.53 + return applyCode(loader, name, code);
1.54 + }
1.55 +
1.56 + @JavaScriptBody(args = {"loader", "name", "script" }, body =
1.57 + "try {\n" +
1.58 + " new Function(script)(loader, name);\n" +
1.59 + "} catch (ex) {\n" +
1.60 + " throw 'Cannot compile ' + ex + ' script:\\\\n' + script;\n" +
1.61 + "}\n" +
1.62 + "return vm[name](false);\n"
1.63 + )
1.64 + private static native Object applyCode(Object loader, String name, String script);
1.65 +
1.66 + private static String toJavaScript(Object loader, byte[] is) throws IOException {
1.67 + StringBuilder sb = new StringBuilder();
1.68 + sb.append("var loader = arguments[0];\n");
1.69 + sb.append("var vm = loader.vm;\n");
1.70 + new VMLazy(loader, sb).compile(new ByteArrayInputStream(is));
1.71 + return sb.toString().toString();
1.72 + }
1.73 +
1.74 + @JavaScriptBody(args = { "self", "n" },
1.75 + body=
1.76 + "var cls = n.replace__Ljava_lang_String_2CC(n,'/','_').toString();"
1.77 + + "var loader = self.fld_loader;"
1.78 + + "var vm = loader.vm;"
1.79 + + "if (vm[cls]) return false;"
1.80 + + "vm[cls] = function() {"
1.81 + + " return loader.loadClass(n,cls);"
1.82 + + "};"
1.83 + + "return true;"
1.84 + )
1.85 + @Override
1.86 + protected boolean requireReference(String internalClassName) {
1.87 + throw new UnsupportedOperationException();
1.88 + }
1.89 +
1.90 + @Override
1.91 + protected void requireScript(String resourcePath) {
1.92 + }
1.93 +
1.94 + @Override
1.95 + String assignClass(String className) {
1.96 + return "vm[arguments[1]]=";
1.97 + }
1.98 +
1.99 + @Override
1.100 + String accessClass(String classOperation) {
1.101 + return "vm." + classOperation;
1.102 + }
1.103 +}