1.1 --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Fri Sep 21 10:14:25 2012 +0200
1.2 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Sep 24 09:35:00 2012 +0200
1.3 @@ -19,6 +19,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 +import java.util.ArrayList;
1.8 import java.util.Collection;
1.9 import java.util.List;
1.10 import static org.netbeans.modules.classfile.ByteCodes.*;
1.11 @@ -26,6 +27,7 @@
1.12 import org.netbeans.modules.classfile.CPEntry;
1.13 import org.netbeans.modules.classfile.CPFieldInfo;
1.14 import org.netbeans.modules.classfile.CPMethodInfo;
1.15 +import org.netbeans.modules.classfile.CPStringInfo;
1.16 import org.netbeans.modules.classfile.ClassFile;
1.17 import org.netbeans.modules.classfile.ClassName;
1.18 import org.netbeans.modules.classfile.Code;
1.19 @@ -71,9 +73,10 @@
1.20 ByteCodeToJavaScript compiler = new ByteCodeToJavaScript(
1.21 jc, out, references
1.22 );
1.23 + List<String> toInitilize = new ArrayList<String>();
1.24 for (Method m : jc.getMethods()) {
1.25 if (m.isStatic()) {
1.26 - compiler.generateStaticMethod(m);
1.27 + compiler.generateStaticMethod(m, toInitilize);
1.28 } else {
1.29 compiler.generateInstanceMethod(m);
1.30 }
1.31 @@ -101,14 +104,21 @@
1.32 out.append("\n}");
1.33 ClassName sc = jc.getSuperClass();
1.34 if (sc != null) {
1.35 - out.append("\n ").append(className)
1.36 + out.append("\n").append(className)
1.37 .append(".prototype = new ").append(sc.getInternalName().replace('/', '_'));
1.38 }
1.39 + for (String init : toInitilize) {
1.40 + out.append("\n").append(init).append("();");
1.41 + }
1.42 }
1.43 - private void generateStaticMethod(Method m) throws IOException {
1.44 + private void generateStaticMethod(Method m, List<String> toInitilize) throws IOException {
1.45 + final String mn = findMethodName(m);
1.46 out.append("\nfunction ").append(
1.47 jc.getName().getInternalName().replace('/', '_')
1.48 - ).append('_').append(findMethodName(m));
1.49 + ).append('_').append(mn);
1.50 + if (mn.equals("classV")) {
1.51 + toInitilize.add(jc.getName().getInternalName().replace('/', '_') + '_' + mn);
1.52 + }
1.53 out.append('(');
1.54 String space = "";
1.55 List<Parameter> args = m.getParameters();
1.56 @@ -131,9 +141,7 @@
1.57 out.append(" var ");
1.58 out.append("arg").append(String.valueOf(i)).append(";\n");
1.59 }
1.60 - out.append(" var stack = new Array(");
1.61 - out.append(Integer.toString(code.getMaxStack()));
1.62 - out.append(");\n");
1.63 + out.append(" var stack = new Array();\n");
1.64 produceCode(code.getByteCodes());
1.65 } else {
1.66 out.append(" /* no code found for ").append(m.getTypeSignature()).append(" */\n");
1.67 @@ -361,9 +369,10 @@
1.68 out.append("stack.push(5);");
1.69 break;
1.70 case bc_ldc: {
1.71 - int indx = byteCodes[i++];
1.72 + int indx = byteCodes[++i];
1.73 CPEntry entry = jc.getConstantPool().get(indx);
1.74 - out.append("stack.push(" + entry.getValue() + ");");
1.75 + String v = encodeConstant(entry);
1.76 + out.append("stack.push(").append(v).append(");");
1.77 break;
1.78 }
1.79 case bc_ldc_w:
1.80 @@ -371,7 +380,8 @@
1.81 int indx = readIntArg(byteCodes, i);
1.82 CPEntry entry = jc.getConstantPool().get(indx);
1.83 i += 2;
1.84 - out.append("stack.push(" + entry.getValue() + ");");
1.85 + String v = encodeConstant(entry);
1.86 + out.append("stack.push(").append(v).append(");");
1.87 break;
1.88 }
1.89 case bc_lcmp:
1.90 @@ -483,6 +493,41 @@
1.91 i += 2;
1.92 break;
1.93 }
1.94 + case bc_newarray: {
1.95 + int type = byteCodes[i++];
1.96 + out.append("stack.push(new Array(stack.pop()));");
1.97 + break;
1.98 + }
1.99 + case bc_anewarray: {
1.100 + i += 2; // skip type of array
1.101 + out.append("stack.push(new Array(stack.pop()));");
1.102 + break;
1.103 + }
1.104 + case bc_arraylength:
1.105 + out.append("stack.push(stack.pop().length);");
1.106 + break;
1.107 + case bc_iastore:
1.108 + case bc_lastore:
1.109 + case bc_fastore:
1.110 + case bc_dastore:
1.111 + case bc_aastore:
1.112 + case bc_bastore:
1.113 + case bc_castore:
1.114 + case bc_sastore: {
1.115 + out.append("{ var value = stack.pop(); var indx = stack.pop(); stack.pop()[indx] = value; }");
1.116 + break;
1.117 + }
1.118 + case bc_iaload:
1.119 + case bc_laload:
1.120 + case bc_faload:
1.121 + case bc_daload:
1.122 + case bc_aaload:
1.123 + case bc_baload:
1.124 + case bc_caload:
1.125 + case bc_saload: {
1.126 + out.append("{ var indx = stack.pop(); stack.push(stack.pop()[indx]); }");
1.127 + break;
1.128 + }
1.129 case bc_dup:
1.130 out.append("stack.push(stack[stack.length - 1]);");
1.131 break;
1.132 @@ -492,7 +537,7 @@
1.133 case bc_getfield: {
1.134 int indx = readIntArg(byteCodes, i);
1.135 CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
1.136 - out.append(" stack.push(stack.pop().").append(fi.getFieldName()).append(");");
1.137 + out.append("stack.push(stack.pop().").append(fi.getFieldName()).append(");");
1.138 i += 2;
1.139 break;
1.140 }
1.141 @@ -735,4 +780,14 @@
1.142 out.append(d);
1.143 }
1.144 }
1.145 +
1.146 + private String encodeConstant(CPEntry entry) {
1.147 + final String v;
1.148 + if (entry instanceof CPStringInfo) {
1.149 + v = "\"" + entry.getValue().toString().replace("\"", "\\\"") + "\"";
1.150 + } else {
1.151 + v = entry.getValue().toString();
1.152 + }
1.153 + return v;
1.154 + }
1.155 }