1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Aug 31 22:36:54 2014 +0200
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Sep 13 18:33:05 2014 +0200
1.3 @@ -19,7 +19,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 -import java.util.Locale;
1.8 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.9 import static org.apidesign.vm4brwsr.ByteCodeParser.*;
1.10
1.11 /** Translator of the code inside class files to JavaScript.
1.12 @@ -258,9 +258,22 @@
1.13 append("\n ").append(destObject).append(".").append(mn).append(".cls = CLS;");
1.14 }
1.15 append("\n c.constructor = CLS;");
1.16 - append("\n function fillInstOf(x) {");
1.17 + append("\n function ").append(className).append("fillInstOf(x) {");
1.18 String instOfName = "$instOf_" + className;
1.19 append("\n Object.defineProperty(x, '").append(instOfName).append("', { value : true });");
1.20 + if (jc.isInterface()) {
1.21 + for (MethodData m : jc.getMethods()) {
1.22 + if ((m.getAccess() & ACC_ABSTRACT) == 0
1.23 + && (m.getAccess() & ACC_STATIC) == 0
1.24 + && (m.getAccess() & ACC_PRIVATE) == 0) {
1.25 + final String mn = findMethodName(m, new StringBuilder());
1.26 + append("\n try {");
1.27 + append("\n if (!x['").append(mn).append("']) Object.defineProperty(x, '").append(mn).append("', { value : c['").append(mn).append("']});");
1.28 + append("\n } catch (ignore) {");
1.29 + append("\n }");
1.30 + }
1.31 + }
1.32 + }
1.33 for (String superInterface : jc.getSuperInterfaces()) {
1.34 String intrfc = superInterface.replace('/', '_');
1.35 append("\n vm.").append(intrfc).append("(false)['fillInstOf'](x);");
1.36 @@ -268,8 +281,8 @@
1.37 }
1.38 append("\n }");
1.39 append("\n try {");
1.40 - append("\n Object.defineProperty(c, 'fillInstOf', { value: fillInstOf });");
1.41 - append("\n fillInstOf(c);");
1.42 + append("\n Object.defineProperty(c, 'fillInstOf', { value: ").append(className).append("fillInstOf });");
1.43 + append("\n ").append(className).append("fillInstOf(c);");
1.44 append("\n } catch (ignore) {");
1.45 append("\n }");
1.46 // obfuscationDelegate.exportJSProperty(this, "c", instOfName);
1.47 @@ -1051,6 +1064,49 @@
1.48 case opc_invokestatic:
1.49 i = invokeStaticMethod(byteCodes, i, smapper, true);
1.50 break;
1.51 + case opc_invokedynamic: {
1.52 + int indx = readUShortArg(byteCodes, i);
1.53 + println("invoke dynamic: " + indx);
1.54 + ByteCodeParser.CPX2 c2 = jc.getCpoolEntry(indx);
1.55 + BootMethodData bm = jc.getBootMethod(c2.cpx1);
1.56 + CPX2 methodHandle = jc.getCpoolEntry(bm.method);
1.57 + println(" type: " + methodHandle.cpx1);
1.58 + String[] mi = jc.getFieldInfoName(methodHandle.cpx2);
1.59 + String mcn = mangleClassName(mi[0]);
1.60 + char[] returnType = {'V'};
1.61 + StringBuilder cnt = new StringBuilder();
1.62 + String mn = findMethodName(mi, cnt, returnType);
1.63 + println(" mi[0]: " + mi[0]);
1.64 + println(" mi[1]: " + mi[1]);
1.65 + println(" mi[2]: " + mi[2]);
1.66 + println(" mn : " + mn);
1.67 + println(" name and type: " + jc.stringValue(c2.cpx2, true));
1.68 + CPX2 nameAndType = jc.getCpoolEntry(c2.cpx2);
1.69 + String type = jc.StringValue(nameAndType.cpx2);
1.70 + String object = accessClass(mcn) + "(false)";
1.71 + if (mn.startsWith("cons_")) {
1.72 + object += ".constructor";
1.73 + }
1.74 + append("var metHan = ");
1.75 + append(accessStaticMethod(object, mn, mi));
1.76 + append('(');
1.77 + String lookup = accessClass("java_lang_invoke_MethodHandles") + "(false).findFor__Ljava_lang_invoke_MethodHandles$Lookup_2Ljava_lang_Class_2(CLS.$class)";
1.78 + append(lookup);
1.79 + append(", '").append(mi[1]).append("', ");
1.80 + String methodType = accessClass("java_lang_invoke_MethodType") + "(false).fromMethodDescriptorString__Ljava_lang_invoke_MethodType_2Ljava_lang_String_2Ljava_lang_ClassLoader_2(";
1.81 + append(methodType).append("'").append(type).append("', null)");
1.82 +// if (numArguments > 0) {
1.83 +// append(vars[0]);
1.84 +// for (int j = 1; j < numArguments; ++j) {
1.85 +// append(", ");
1.86 +// append(vars[j]);
1.87 +// }
1.88 +// }
1.89 + append(");");
1.90 + emit(smapper, this, "throw 'Invoke dynamic: ' + @1 + ': ' + metHan;", "" + indx);
1.91 + i += 4;
1.92 + break;
1.93 + }
1.94 case opc_new: {
1.95 int indx = readUShortArg(byteCodes, i);
1.96 String ci = jc.getClassName(indx);
1.97 @@ -1557,7 +1613,7 @@
1.98 sb.append(ch);
1.99 } else {
1.100 sb.append("_0");
1.101 - String hex = Integer.toHexString(ch).toLowerCase(Locale.ENGLISH);
1.102 + String hex = Integer.toHexString(ch).toLowerCase();
1.103 for (int m = hex.length(); m < 4; m++) {
1.104 sb.append("0");
1.105 }
1.106 @@ -2310,4 +2366,9 @@
1.107 append(Integer.toString(cc));
1.108 }
1.109 }
1.110 +
1.111 + @JavaScriptBody(args = "msg", body = "")
1.112 + private static void println(String msg) {
1.113 + System.err.println(msg);
1.114 + }
1.115 }