Making ready for recursive calls. Providng proper conversions from and to '/', '.' and '_'
1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Dec 07 06:29:54 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Dec 07 10:07:59 2012 +0100
1.3 @@ -25,31 +25,57 @@
1.4 *
1.5 * @author Jaroslav Tulach <jtulach@netbeans.org>
1.6 */
1.7 -class VMLazy extends ByteCodeToJavaScript {
1.8 +final class VMLazy {
1.9 private final Object loader;
1.10 + private final Object[] args;
1.11
1.12 - private VMLazy(Object loader, Appendable out) {
1.13 - super(out);
1.14 + private VMLazy(Object loader, Object[] args) {
1.15 this.loader = loader;
1.16 + this.args = args;
1.17 }
1.18
1.19 static void init() {
1.20 }
1.21
1.22 - @JavaScriptBody(args={"res", "args" }, body = "return args[0](res.toString());")
1.23 - private static native byte[] read(String res, Object[] args);
1.24 + @JavaScriptBody(args={"l", "res", "args" }, body = ""
1.25 + + "try {"
1.26 + + " return args[0](res.toString());"
1.27 + + "} catch (x) {"
1.28 + + " throw Object.getOwnPropertyNames(l.vm).toString() + x.toString();"
1.29 + + "}")
1.30 + private static native byte[] read(Object l, String res, Object[] args);
1.31
1.32 static Object load(Object loader, String name, Object[] arguments)
1.33 throws IOException, ClassNotFoundException {
1.34 + return new VMLazy(loader, arguments).load(name);
1.35 + }
1.36 +
1.37 + private Object load(String name)
1.38 + throws IOException, ClassNotFoundException {
1.39 String res = name.replace('.', '/') + ".class";
1.40 - byte[] arr = read(res, arguments);
1.41 + byte[] arr = read(loader, res, args);
1.42 if (arr == null) {
1.43 throw new ClassNotFoundException(name);
1.44 }
1.45 - String code = toJavaScript(loader, arr);
1.46 - return applyCode(loader, name, code);
1.47 +// beingDefined(loader, name);
1.48 + StringBuilder out = new StringBuilder();
1.49 + out.append("var loader = arguments[0];\n");
1.50 + out.append("var vm = loader.vm;\n");
1.51 + new Gen(this, out).compile(new ByteArrayInputStream(arr));
1.52 + String code = out.toString().toString();
1.53 + String under = name.replace('.', '_');
1.54 + return applyCode(loader, under, code);
1.55 }
1.56 +
1.57 +/* possibly not needed:
1.58 + @JavaScriptBody(args = {"loader", "n" }, body =
1.59 + "var cls = n.replace__Ljava_lang_String_2CC(n, '.','_').toString();" +
1.60 + "loader.vm[cls] = true;\n"
1.61 + )
1.62 + private static native void beingDefined(Object loader, String name);
1.63 +*/
1.64
1.65 +
1.66 @JavaScriptBody(args = {"loader", "name", "script" }, body =
1.67 "try {\n" +
1.68 " new Function(script)(loader, name);\n" +
1.69 @@ -60,41 +86,44 @@
1.70 )
1.71 private static native Object applyCode(Object loader, String name, String script);
1.72
1.73 - private static String toJavaScript(Object loader, byte[] is) throws IOException {
1.74 - StringBuilder sb = new StringBuilder();
1.75 - sb.append("var loader = arguments[0];\n");
1.76 - sb.append("var vm = loader.vm;\n");
1.77 - new VMLazy(loader, sb).compile(new ByteArrayInputStream(is));
1.78 - return sb.toString().toString();
1.79 - }
1.80 +
1.81 + private static final class Gen extends ByteCodeToJavaScript {
1.82 + private final VMLazy lazy;
1.83
1.84 - @JavaScriptBody(args = { "self", "n" },
1.85 - body=
1.86 - "var cls = n.replace__Ljava_lang_String_2CC(n,'/','_').toString();"
1.87 - + "var loader = self.fld_loader;"
1.88 - + "var vm = loader.vm;"
1.89 - + "if (vm[cls]) return false;"
1.90 - + "vm[cls] = function() {"
1.91 - + " return loader.loadClass(n,cls);"
1.92 - + "};"
1.93 - + "return true;"
1.94 - )
1.95 - @Override
1.96 - protected boolean requireReference(String internalClassName) {
1.97 - throw new UnsupportedOperationException();
1.98 - }
1.99 + public Gen(VMLazy vm, Appendable out) {
1.100 + super(out);
1.101 + this.lazy = vm;
1.102 + }
1.103 +
1.104 + @JavaScriptBody(args = {"self", "n"},
1.105 + body =
1.106 + "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();"
1.107 + + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();"
1.108 + + "\nvar lazy = self.fld_lazy;"
1.109 + + "\nvar loader = lazy.fld_loader;"
1.110 + + "\nvar vm = loader.vm;"
1.111 + + "\nif (vm[cls]) return false;"
1.112 + + "\nvm[cls] = function() {"
1.113 + + "\n return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2(lazy, dot);"
1.114 + + "\n};"
1.115 + + "\nreturn true;")
1.116 + @Override
1.117 + protected boolean requireReference(String internalClassName) {
1.118 + throw new UnsupportedOperationException();
1.119 + }
1.120
1.121 - @Override
1.122 - protected void requireScript(String resourcePath) {
1.123 - }
1.124 + @Override
1.125 + protected void requireScript(String resourcePath) {
1.126 + }
1.127
1.128 - @Override
1.129 - String assignClass(String className) {
1.130 - return "vm[arguments[1]]=";
1.131 - }
1.132 + @Override
1.133 + String assignClass(String className) {
1.134 + return "vm[arguments[1]]=";
1.135 + }
1.136
1.137 - @Override
1.138 - String accessClass(String classOperation) {
1.139 - return "vm." + classOperation;
1.140 + @Override
1.141 + String accessClass(String classOperation) {
1.142 + return "vm." + classOperation;
1.143 + }
1.144 }
1.145 }