1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Dec 12 11:04:02 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 14 11:15:37 2012 +0100
1.3 @@ -19,6 +19,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.8 import org.apidesign.javap.AnnotationParser;
1.9 import org.apidesign.javap.ClassData;
1.10 import org.apidesign.javap.FieldData;
1.11 @@ -30,7 +31,7 @@
1.12 *
1.13 * @author Jaroslav Tulach <jtulach@netbeans.org>
1.14 */
1.15 -public abstract class ByteCodeToJavaScript {
1.16 +abstract class ByteCodeToJavaScript {
1.17 private ClassData jc;
1.18 final Appendable out;
1.19
1.20 @@ -57,9 +58,12 @@
1.21 *
1.22 * @param className suggested name of the class
1.23 */
1.24 - protected String assignClass(String className) {
1.25 + /* protected */ String assignClass(String className) {
1.26 return className + " = ";
1.27 }
1.28 + /* protected */ String accessClass(String classOperation) {
1.29 + return classOperation;
1.30 + }
1.31
1.32 /**
1.33 * Converts a given class file to a JavaScript version.
1.34 @@ -100,12 +104,15 @@
1.35 if (proto == null) {
1.36 String sc = jc.getSuperClassName(); // with _
1.37 out.append("\n var pp = ").
1.38 - append(sc.replace('/', '_')).append("(true);");
1.39 + append(accessClass(sc.replace('/', '_'))).append("(true);");
1.40 out.append("\n var p = CLS.prototype = pp;");
1.41 out.append("\n var c = p;");
1.42 out.append("\n var sprcls = pp.constructor.$class;");
1.43 } else {
1.44 out.append("\n var p = CLS.prototype = ").append(proto[1]).append(";");
1.45 + if (proto[0] == null) {
1.46 + proto[0] = "p";
1.47 + }
1.48 out.append("\n var c = ").append(proto[0]).append(";");
1.49 out.append("\n var sprcls = null;");
1.50 }
1.51 @@ -140,7 +147,8 @@
1.52 for (String superInterface : jc.getSuperInterfaces()) {
1.53 out.append("\n c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
1.54 }
1.55 - out.append("\n CLS.$class = java_lang_Class(true);");
1.56 + out.append("\n CLS.$class = ");
1.57 + out.append(accessClass("java_lang_Class(true);"));
1.58 out.append("\n CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
1.59 out.append("\n CLS.$class.superclass = sprcls;");
1.60 out.append("\n CLS.$class.cnstr = CLS;");
1.61 @@ -190,7 +198,7 @@
1.62 }
1.63 final String mn = findMethodName(m, new StringBuilder());
1.64 if (mn.equals("class__V")) {
1.65 - toInitilize.add(className(jc) + "(false)." + mn);
1.66 + toInitilize.add(accessClass(className(jc)) + "(false)." + mn);
1.67 }
1.68 generateMethod(prefix, mn, m);
1.69 return mn;
1.70 @@ -849,7 +857,7 @@
1.71 int indx = readIntArg(byteCodes, i);
1.72 String ci = jc.getClassName(indx);
1.73 emit(out, "@1 = new @2;",
1.74 - smapper.pushA(), ci.replace('/', '_'));
1.75 + smapper.pushA(), accessClass(ci.replace('/', '_')));
1.76 addReference(ci);
1.77 i += 2;
1.78 break;
1.79 @@ -1017,7 +1025,8 @@
1.80 String[] fi = jc.getFieldInfoName(indx);
1.81 final int type = VarType.fromFieldType(fi[2].charAt(0));
1.82 emit(out, "@1 = @2.@3;",
1.83 - smapper.pushT(type), fi[0].replace('/', '_'), fi[1]);
1.84 + smapper.pushT(type),
1.85 + accessClass(fi[0].replace('/', '_')), fi[1]);
1.86 i += 2;
1.87 addReference(fi[0]);
1.88 break;
1.89 @@ -1036,7 +1045,8 @@
1.90 String[] fi = jc.getFieldInfoName(indx);
1.91 final int type = VarType.fromFieldType(fi[2].charAt(0));
1.92 emit(out, "@1.@2 = @3;",
1.93 - fi[0].replace('/', '_'), fi[1], smapper.popT(type));
1.94 + accessClass(fi[0].replace('/', '_')), fi[1],
1.95 + smapper.popT(type));
1.96 i += 2;
1.97 addReference(fi[0]);
1.98 break;
1.99 @@ -1047,7 +1057,8 @@
1.100 if (!type.startsWith("[")) {
1.101 // no way to check arrays right now
1.102 // XXX proper exception
1.103 - emit(out, "if (@1.$instOf_@2 != 1) throw {};",
1.104 + emit(out,
1.105 + "if (@1 !== null && !@1.$instOf_@2) throw {};",
1.106 smapper.getA(0), type.replace('/', '_'));
1.107 }
1.108 i += 2;
1.109 @@ -1057,7 +1068,8 @@
1.110 int indx = readIntArg(byteCodes, i);
1.111 final String type = jc.getClassName(indx);
1.112 emit(out, "@2 = @1.$instOf_@3 ? 1 : 0;",
1.113 - smapper.popA(), smapper.pushI(), type.replace('/', '_'));
1.114 + smapper.popA(), smapper.pushI(),
1.115 + type.replace('/', '_'));
1.116 i += 2;
1.117 break;
1.118 }
1.119 @@ -1265,7 +1277,7 @@
1.120 }
1.121
1.122 final String in = mi[0];
1.123 - out.append(in.replace('/', '_'));
1.124 + out.append(accessClass(in.replace('/', '_')));
1.125 out.append("(false).");
1.126 out.append(mn);
1.127 out.append('(');
1.128 @@ -1339,6 +1351,7 @@
1.129 String s = jc.stringValue(entryIndex, classRef);
1.130 if (classRef[0] != null) {
1.131 addReference(classRef[0]);
1.132 + s = accessClass(s.replace('/', '_')) + "(false).constructor.$class";
1.133 }
1.134 return s;
1.135 }
1.136 @@ -1383,8 +1396,7 @@
1.137 String space;
1.138 int index;
1.139 if (!isStatic) {
1.140 - out.append(p.args[0]);
1.141 - space = ",";
1.142 + space = outputArg(out, p.args, 0);
1.143 index = 1;
1.144 } else {
1.145 space = "";
1.146 @@ -1392,9 +1404,8 @@
1.147 }
1.148 for (int i = 0; i < cnt.length(); i++) {
1.149 out.append(space);
1.150 - out.append(p.args[index]);
1.151 + space = outputArg(out, p.args, index);
1.152 index++;
1.153 - space = ",";
1.154 }
1.155 out.append(") {").append("\n");
1.156 out.append(p.body);
1.157 @@ -1487,6 +1498,18 @@
1.158 ap.parse(data, cd);
1.159 }
1.160
1.161 + private static String outputArg(Appendable out, String[] args, int indx) throws IOException {
1.162 + final String name = args[indx];
1.163 + if (name == null) {
1.164 + return "";
1.165 + }
1.166 + if (name.contains(",")) {
1.167 + throw new IOException("Wrong parameter with ',': " + name);
1.168 + }
1.169 + out.append(name);
1.170 + return ",";
1.171 + }
1.172 +
1.173 private static void emit(final Appendable out,
1.174 final String format,
1.175 final CharSequence... params) throws IOException {
1.176 @@ -1511,5 +1534,4 @@
1.177
1.178 out.append(format, processed, length);
1.179 }
1.180 -
1.181 }