src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java
changeset 21 d8807b6a636a
parent 20 0e7dd9e2e31e
     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  }