vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
branchregisters
changeset 587 a7a45e5e5e77
parent 585 fe1a07c17681
parent 571 62c327a1e23f
child 592 5e13b1ac2886
     1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Jan 25 15:38:12 2013 +0100
     1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Jan 25 15:44:09 2013 +0100
     1.3 @@ -52,7 +52,7 @@
     1.4      /*
     1.5       * @param resourcePath name of resources to read
     1.6       */
     1.7 -    protected abstract void requireScript(String resourcePath);
     1.8 +    protected abstract void requireScript(String resourcePath) throws IOException;
     1.9      
    1.10      /** Allows subclasses to redefine what field a function representing a
    1.11       * class gets assigned. By default it returns the suggested name followed
    1.12 @@ -212,7 +212,7 @@
    1.13          out.append("\n    return this;");
    1.14          out.append("\n  }");
    1.15          out.append("\n  return arguments[0] ? new CLS() : CLS.prototype;");
    1.16 -        out.append("\n}");
    1.17 +        out.append("\n};");
    1.18          StringBuilder sb = new StringBuilder();
    1.19          for (String init : toInitilize.toArray()) {
    1.20              sb.append("\n").append(init).append("();");
    1.21 @@ -945,7 +945,7 @@
    1.22                          case 11: jvmType = "[J"; break;
    1.23                          default: throw new IllegalStateException("Array type: " + atype);
    1.24                      }
    1.25 -                    emit(out, "var @2 = new Array(@1).initWith('@3', 0);",
    1.26 +                    emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
    1.27                           smapper.popI(), smapper.pushA(), jvmType);
    1.28                      break;
    1.29                  case opc_anewarray: {
    1.30 @@ -957,7 +957,7 @@
    1.31                      } else {
    1.32                          typeName = "[L" + typeName + ";";
    1.33                      }
    1.34 -                    emit(out, "var @2 = new Array(@1).initWith('@3', null);",
    1.35 +                    emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
    1.36                           smapper.popI(), smapper.pushA(), typeName);
    1.37                      break;
    1.38                  }
    1.39 @@ -966,27 +966,17 @@
    1.40                      i += 2;
    1.41                      String typeName = jc.getClassName(type);
    1.42                      int dim = readUByte(byteCodes, ++i);
    1.43 -                    out.append("{ var a0 = new Array(").append(smapper.popI())
    1.44 -                       .append(").initWith('").append(typeName).append("', null);");
    1.45 -                    for (int d = 1; d < dim; d++) {
    1.46 -                        typeName = typeName.substring(1);
    1.47 -                        out.append("\n  var l" + d).append(" = ")
    1.48 -                           .append(smapper.popI()).append(';');
    1.49 -                        out.append("\n  for (var i" + d).append (" = 0; i" + d).
    1.50 -                            append(" < a" + (d - 1)).
    1.51 -                            append(".length; i" + d).append("++) {");
    1.52 -                        out.append("\n    var a" + d).
    1.53 -                            append (" = new Array(l" + d).append(").initWith('")
    1.54 -                            .append(typeName).append("', ")
    1.55 -                            .append(typeName.length() == 2 ? "0" : "null").append(");");
    1.56 -                        out.append("\n    a" + (d - 1)).append("[i" + d).append("] = a" + d).
    1.57 -                            append(";");
    1.58 +                    StringBuilder dims = new StringBuilder();
    1.59 +                    dims.append('[');
    1.60 +                    for (int d = 0; d < dim; d++) {
    1.61 +                        if (d != 0) {
    1.62 +                            dims.append(",");
    1.63 +                        }
    1.64 +                        dims.append(smapper.popI());
    1.65                      }
    1.66 -                    for (int d = 1; d < dim; d++) {
    1.67 -                        out.append("\n  }");
    1.68 -                    }
    1.69 -                    out.append("\nvar ").append(smapper.pushA())
    1.70 -                                        .append(" = a0; }");
    1.71 +                    dims.append(']');
    1.72 +                    emit(out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
    1.73 +                         dims.toString(), smapper.pushA(), typeName);
    1.74                      break;
    1.75                  }
    1.76                  case opc_arraylength:
    1.77 @@ -1247,11 +1237,13 @@
    1.78                      int indx = readIntArg(byteCodes, i);
    1.79                      final String type = jc.getClassName(indx);
    1.80                      if (!type.startsWith("[")) {
    1.81 -                        // no way to check arrays right now
    1.82 -                        // XXX proper exception
    1.83                          emit(out,
    1.84                               "if (@1 !== null && !@1.$instOf_@2) throw {};",
    1.85                               smapper.getA(0), type.replace('/', '_'));
    1.86 +                    } else {
    1.87 +                        emit(out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
    1.88 +                             smapper.getA(0), type
    1.89 +                        );
    1.90                      }
    1.91                      i += 2;
    1.92                      break;
    1.93 @@ -1259,9 +1251,16 @@
    1.94                  case opc_instanceof: {
    1.95                      int indx = readIntArg(byteCodes, i);
    1.96                      final String type = jc.getClassName(indx);
    1.97 -                    emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;",
    1.98 -                         smapper.popA(), smapper.pushI(),
    1.99 -                         type.replace('/', '_'));
   1.100 +                    if (!type.startsWith("[")) {
   1.101 +                        emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;",
   1.102 +                             smapper.popA(), smapper.pushI(),
   1.103 +                             type.replace('/', '_'));
   1.104 +                    } else {
   1.105 +                        emit(out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
   1.106 +                            smapper.popA(), smapper.pushI(),
   1.107 +                            type
   1.108 +                        );
   1.109 +                    }
   1.110                      i += 2;
   1.111                      break;
   1.112                  }
   1.113 @@ -1567,8 +1566,12 @@
   1.114          String[] classRef = { null };
   1.115          String s = jc.stringValue(entryIndex, classRef);
   1.116          if (classRef[0] != null) {
   1.117 -            addReference(classRef[0]);
   1.118 -            s = accessClass(s.replace('/', '_')) + "(false).constructor.$class";
   1.119 +            if (classRef[0].startsWith("[")) {
   1.120 +                s = accessClass("java_lang_Class") + "(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('" + classRef[0] + "');";
   1.121 +            } else {
   1.122 +                addReference(classRef[0]);
   1.123 +                s = accessClass(s.replace('/', '_')) + "(false).constructor.$class";
   1.124 +            }
   1.125          }
   1.126          return s;
   1.127      }