Making ByteCodeToJavaScript an Appendable to track when something is generated
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 29 Apr 2014 16:22:23 +0200
changeset 150916f50abb439b
parent 1484 76cdd49e774b
child 1510 b242abb07fbf
Making ByteCodeToJavaScript an Appendable to track when something is generated
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Apr 23 17:48:43 2014 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Apr 29 16:22:23 2014 +0200
     1.3 @@ -25,9 +25,10 @@
     1.4   *
     1.5   * @author Jaroslav Tulach <jtulach@netbeans.org>
     1.6   */
     1.7 -abstract class ByteCodeToJavaScript {
     1.8 +abstract class ByteCodeToJavaScript implements Appendable {
     1.9      private ClassData jc;
    1.10 -    final Appendable out;
    1.11 +    private final Appendable out;
    1.12 +    private boolean outChanged;
    1.13      final ObfuscationDelegate obfuscationDelegate;
    1.14  
    1.15      protected ByteCodeToJavaScript(Appendable out) {
    1.16 @@ -40,6 +41,27 @@
    1.17          this.obfuscationDelegate = obfuscationDelegate;
    1.18      }
    1.19      
    1.20 +    @Override
    1.21 +    public final Appendable append(CharSequence csq) throws IOException {
    1.22 +        out.append(csq);
    1.23 +        outChanged = true;
    1.24 +        return this;
    1.25 +    }
    1.26 +
    1.27 +    @Override
    1.28 +    public final Appendable append(CharSequence csq, int start, int end) throws IOException {
    1.29 +        out.append(csq, start, end);
    1.30 +        outChanged = true;
    1.31 +        return this;
    1.32 +    }
    1.33 +
    1.34 +    @Override
    1.35 +    public final Appendable append(char c) throws IOException {
    1.36 +        out.append(c);
    1.37 +        outChanged = true;
    1.38 +        return this;
    1.39 +    }
    1.40 +    
    1.41      /* Collects additional required resources.
    1.42       * 
    1.43       * @param internalClassName classes that were referenced and should be loaded in order the
    1.44 @@ -75,7 +97,7 @@
    1.45       * @throws IOException 
    1.46       */
    1.47      boolean debug(String msg) throws IOException {
    1.48 -        out.append(msg);
    1.49 +        append(msg);
    1.50          return true;
    1.51      }
    1.52  
    1.53 @@ -132,24 +154,24 @@
    1.54          );
    1.55          StringArray toInitilize = new StringArray();
    1.56          final String className = className(jc);
    1.57 -        out.append("\n\n").append(assignClass(className));
    1.58 -        out.append("function ").append(className).append("() {");
    1.59 -        out.append("\n  var CLS = ").append(className).append(';');
    1.60 -        out.append("\n  if (!CLS.$class) {");
    1.61 +        append("\n\n").append(assignClass(className));
    1.62 +        append("function ").append(className).append("() {");
    1.63 +        append("\n  var CLS = ").append(className).append(';');
    1.64 +        append("\n  if (!CLS.$class) {");
    1.65          if (proto == null) {
    1.66              String sc = jc.getSuperClassName(); // with _
    1.67 -            out.append("\n    var pp = ").
    1.68 +            append("\n    var pp = ").
    1.69                  append(accessClass(mangleClassName(sc))).append("(true);");
    1.70 -            out.append("\n    var p = CLS.prototype = pp;");
    1.71 -            out.append("\n    var c = p;");
    1.72 -            out.append("\n    var sprcls = pp.constructor.$class;");
    1.73 +            append("\n    var p = CLS.prototype = pp;");
    1.74 +            append("\n    var c = p;");
    1.75 +            append("\n    var sprcls = pp.constructor.$class;");
    1.76          } else {
    1.77 -            out.append("\n    var p = CLS.prototype = ").append(proto[1]).append(";");
    1.78 +            append("\n    var p = CLS.prototype = ").append(proto[1]).append(";");
    1.79              if (proto[0] == null) {
    1.80                  proto[0] = "p";
    1.81              }
    1.82 -            out.append("\n    var c = ").append(proto[0]).append(";");
    1.83 -            out.append("\n    var sprcls = null;");
    1.84 +            append("\n    var c = ").append(proto[0]).append(";");
    1.85 +            append("\n    var sprcls = null;");
    1.86          }
    1.87          for (FieldData v : jc.getFields()) {
    1.88              if (v.isStatic()) {
    1.89 @@ -158,13 +180,13 @@
    1.90                          continue;
    1.91                      }
    1.92                  }
    1.93 -                out.append("\n  CLS.fld_").append(v.getName()).append(initField(v));
    1.94 -                out.append("\n  c._").append(v.getName()).append(" = function (v) {")
    1.95 +                append("\n  CLS.fld_").append(v.getName()).append(initField(v));
    1.96 +                append("\n  c._").append(v.getName()).append(" = function (v) {")
    1.97                     .append("  if (arguments.length == 1) CLS.fld_").append(v.getName())
    1.98                     .append(" = v; return CLS.fld_").
    1.99                      append(v.getName()).append("; };");
   1.100              } else {
   1.101 -                out.append("\n  c._").append(v.getName()).append(" = function (v) {")
   1.102 +                append("\n  c._").append(v.getName()).append(" = function (v) {")
   1.103                     .append("  if (arguments.length == 1) this.fld_").
   1.104                      append(className).append('_').append(v.getName())
   1.105                     .append(" = v; return this.fld_").
   1.106 @@ -172,7 +194,7 @@
   1.107                     .append("; };");
   1.108              }
   1.109  
   1.110 -            obfuscationDelegate.exportField(out, "c", "_" + v.getName(), v);
   1.111 +            obfuscationDelegate.exportField(this, "c", "_" + v.getName(), v);
   1.112          }
   1.113          for (MethodData m : jc.getMethods()) {
   1.114              byte[] onlyArr = m.findAnnotationData(true);
   1.115 @@ -182,14 +204,14 @@
   1.116              );
   1.117              if (only != null) {
   1.118                  if (only[0] != null && only[1] != null) {
   1.119 -                    out.append("\n    p.").append(only[0]).append(" = ")
   1.120 +                    append("\n    p.").append(only[0]).append(" = ")
   1.121                          .append(only[1]).append(";");
   1.122                  }
   1.123                  continue;
   1.124              }
   1.125              String destObject;
   1.126              String mn;
   1.127 -            out.append("\n    ");
   1.128 +            append("\n    ");
   1.129              if (m.isStatic()) {
   1.130                  destObject = "c";
   1.131                  mn = generateStaticMethod(destObject, m, toInitilize);
   1.132 @@ -202,50 +224,50 @@
   1.133                      mn = generateInstanceMethod(destObject, m);
   1.134                  }
   1.135              }
   1.136 -            obfuscationDelegate.exportMethod(out, destObject, mn, m);
   1.137 +            obfuscationDelegate.exportMethod(this, destObject, mn, m);
   1.138              byte[] runAnno = m.findAnnotationData(false);
   1.139              if (runAnno != null) {
   1.140 -                out.append("\n    ").append(destObject).append(".").append(mn).append(".anno = {");
   1.141 -                generateAnno(jc, out, runAnno);
   1.142 -                out.append("\n    };");
   1.143 +                append("\n    ").append(destObject).append(".").append(mn).append(".anno = {");
   1.144 +                generateAnno(jc, runAnno);
   1.145 +                append("\n    };");
   1.146              }
   1.147 -            out.append("\n    ").append(destObject).append(".").append(mn).append(".access = " + m.getAccess()).append(";");
   1.148 -            out.append("\n    ").append(destObject).append(".").append(mn).append(".cls = CLS;");
   1.149 +            append("\n    ").append(destObject).append(".").append(mn).append(".access = " + m.getAccess()).append(";");
   1.150 +            append("\n    ").append(destObject).append(".").append(mn).append(".cls = CLS;");
   1.151          }
   1.152 -        out.append("\n    c.constructor = CLS;");
   1.153 -        out.append("\n    function fillInstOf(x) {");
   1.154 +        append("\n    c.constructor = CLS;");
   1.155 +        append("\n    function fillInstOf(x) {");
   1.156          String instOfName = "$instOf_" + className;
   1.157 -        out.append("\n        x.").append(instOfName).append(" = true;");
   1.158 +        append("\n        x.").append(instOfName).append(" = true;");
   1.159          for (String superInterface : jc.getSuperInterfaces()) {
   1.160              String intrfc = superInterface.replace('/', '_');
   1.161 -            out.append("\n      vm.").append(intrfc).append("(false).fillInstOf(x);");
   1.162 +            append("\n      vm.").append(intrfc).append("(false).fillInstOf(x);");
   1.163              requireReference(superInterface);
   1.164          }
   1.165 -        out.append("\n    }");
   1.166 -        out.append("\n    c.fillInstOf = fillInstOf;");
   1.167 -        out.append("\n    fillInstOf(c);");
   1.168 -        obfuscationDelegate.exportJSProperty(out, "c", instOfName);
   1.169 -        out.append("\n    CLS.$class = 'temp';");
   1.170 -        out.append("\n    CLS.$class = ");
   1.171 -        out.append(accessClass("java_lang_Class(true);"));
   1.172 -        out.append("\n    CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
   1.173 -        out.append("\n    CLS.$class.superclass = sprcls;");
   1.174 -        out.append("\n    CLS.$class.access = ").append(jc.getAccessFlags()+";");
   1.175 -        out.append("\n    CLS.$class.cnstr = CLS;");
   1.176 +        append("\n    }");
   1.177 +        append("\n    c.fillInstOf = fillInstOf;");
   1.178 +        append("\n    fillInstOf(c);");
   1.179 +        obfuscationDelegate.exportJSProperty(this, "c", instOfName);
   1.180 +        append("\n    CLS.$class = 'temp';");
   1.181 +        append("\n    CLS.$class = ");
   1.182 +        append(accessClass("java_lang_Class(true);"));
   1.183 +        append("\n    CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
   1.184 +        append("\n    CLS.$class.superclass = sprcls;");
   1.185 +        append("\n    CLS.$class.access = ").append(jc.getAccessFlags()+";");
   1.186 +        append("\n    CLS.$class.cnstr = CLS;");
   1.187          byte[] classAnno = jc.findAnnotationData(false);
   1.188          if (classAnno != null) {
   1.189 -            out.append("\n    CLS.$class.anno = {");
   1.190 -            generateAnno(jc, out, classAnno);
   1.191 -            out.append("\n    };");
   1.192 +            append("\n    CLS.$class.anno = {");
   1.193 +            generateAnno(jc, classAnno);
   1.194 +            append("\n    };");
   1.195          }
   1.196          for (String init : toInitilize.toArray()) {
   1.197 -            out.append("\n    ").append(init).append("();");
   1.198 +            append("\n    ").append(init).append("();");
   1.199          }
   1.200 -        out.append("\n  }");
   1.201 -        out.append("\n  if (arguments.length === 0) {");
   1.202 -        out.append("\n    if (!(this instanceof CLS)) {");
   1.203 -        out.append("\n      return new CLS();");
   1.204 -        out.append("\n    }");
   1.205 +        append("\n  }");
   1.206 +        append("\n  if (arguments.length === 0) {");
   1.207 +        append("\n    if (!(this instanceof CLS)) {");
   1.208 +        append("\n      return new CLS();");
   1.209 +        append("\n    }");
   1.210          for (FieldData v : jc.getFields()) {
   1.211              byte[] onlyArr = v.findAnnotationData(true);
   1.212              String[] only = findAnnotation(onlyArr, jc, 
   1.213 @@ -254,23 +276,23 @@
   1.214              );
   1.215              if (only != null) {
   1.216                  if (only[0] != null && only[1] != null) {
   1.217 -                    out.append("\n    p.").append(only[0]).append(" = ")
   1.218 +                    append("\n    p.").append(only[0]).append(" = ")
   1.219                          .append(only[1]).append(";");
   1.220                  }
   1.221                  continue;
   1.222              }
   1.223              if (!v.isStatic()) {
   1.224 -                out.append("\n    this.fld_").
   1.225 +                append("\n    this.fld_").
   1.226                      append(className).append('_').
   1.227                      append(v.getName()).append(initField(v));
   1.228              }
   1.229          }
   1.230 -        out.append("\n    return this;");
   1.231 -        out.append("\n  }");
   1.232 -        out.append("\n  return arguments[0] ? new CLS() : CLS.prototype;");
   1.233 -        out.append("\n};");
   1.234 +        append("\n    return this;");
   1.235 +        append("\n  }");
   1.236 +        append("\n  return arguments[0] ? new CLS() : CLS.prototype;");
   1.237 +        append("\n};");
   1.238  
   1.239 -        obfuscationDelegate.exportClass(out, getVMObject(), className, jc);
   1.240 +        obfuscationDelegate.exportClass(this, getVMObject(), className, jc);
   1.241  
   1.242  //        StringBuilder sb = new StringBuilder();
   1.243  //        for (String init : toInitilize.toArray()) {
   1.244 @@ -308,23 +330,23 @@
   1.245          final LocalsMapper lmapper =
   1.246                  new LocalsMapper(stackMapIterator.getArguments());
   1.247  
   1.248 -        out.append(destObject).append(".").append(name).append(" = function(");
   1.249 -        lmapper.outputArguments(out, m.isStatic());
   1.250 -        out.append(") {").append("\n");
   1.251 +        append(destObject).append(".").append(name).append(" = function(");
   1.252 +        lmapper.outputArguments(this, m.isStatic());
   1.253 +        append(") {").append("\n");
   1.254  
   1.255          final byte[] byteCodes = m.getCode();
   1.256          if (byteCodes == null) {
   1.257 -            out.append("  throw 'no code found for ")
   1.258 +            append("  throw 'no code found for ")
   1.259                 .append(jc.getClassName()).append('.')
   1.260                 .append(m.getName()).append("';\n");
   1.261 -            out.append("};");
   1.262 +            append("};");
   1.263              return;
   1.264          }
   1.265  
   1.266          final StackMapper smapper = new StackMapper();
   1.267  
   1.268          if (!m.isStatic()) {
   1.269 -            out.append("  var ").append(" lcA0 = this;\n");
   1.270 +            append("  var ").append(" lcA0 = this;\n");
   1.271          }
   1.272  
   1.273          int lastStackFrame;
   1.274 @@ -337,7 +359,7 @@
   1.275          } else {
   1.276              didBranches = true;
   1.277              lastStackFrame = -1;
   1.278 -            out.append("\n  var gt = 0;\n");
   1.279 +            append("\n  var gt = 0;\n");
   1.280          }
   1.281          
   1.282          int openBraces = 0;
   1.283 @@ -353,13 +375,13 @@
   1.284                  }
   1.285              }
   1.286              if (lastStackFrame != stackMapIterator.getFrameIndex()) {
   1.287 -                smapper.flush(out);
   1.288 +                smapper.flush(this);
   1.289                  if (i != 0) {
   1.290 -                    out.append("    }\n");
   1.291 +                    append("    }\n");
   1.292                  }
   1.293                  if (openBraces > 64) {
   1.294                      for (int c = 0; c < 64; c++) {
   1.295 -                        out.append("break;}\n");
   1.296 +                        append("break;}\n");
   1.297                      }
   1.298                      openBraces = 1;
   1.299                      topMostLabel = i;
   1.300 @@ -368,84 +390,84 @@
   1.301                  lastStackFrame = stackMapIterator.getFrameIndex();
   1.302                  lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
   1.303                  smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
   1.304 -                out.append("    X_" + i).append(": for (;;) { IF: if (gt <= " + i + ") {\n");
   1.305 +                append("    X_" + i).append(": for (;;) { IF: if (gt <= " + i + ") {\n");
   1.306                  openBraces++;
   1.307                  changeInCatch = true;
   1.308              } else {
   1.309                  debug("    /* " + i + " */ ");
   1.310              }
   1.311              if (changeInCatch && trap.useTry()) {
   1.312 -                out.append("try {");
   1.313 +                append("try {");
   1.314                  previousTrap = trap.current();
   1.315              }
   1.316              final int c = readUByte(byteCodes, i);
   1.317              switch (c) {
   1.318                  case opc_aload_0:
   1.319 -                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(0));
   1.320 +                    smapper.assign(this, VarType.REFERENCE, lmapper.getA(0));
   1.321                      break;
   1.322                  case opc_iload_0:
   1.323 -                    smapper.assign(out, VarType.INTEGER, lmapper.getI(0));
   1.324 +                    smapper.assign(this, VarType.INTEGER, lmapper.getI(0));
   1.325                      break;
   1.326                  case opc_lload_0:
   1.327 -                    smapper.assign(out, VarType.LONG, lmapper.getL(0));
   1.328 +                    smapper.assign(this, VarType.LONG, lmapper.getL(0));
   1.329                      break;
   1.330                  case opc_fload_0:
   1.331 -                    smapper.assign(out, VarType.FLOAT, lmapper.getF(0));
   1.332 +                    smapper.assign(this, VarType.FLOAT, lmapper.getF(0));
   1.333                      break;
   1.334                  case opc_dload_0:
   1.335 -                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(0));
   1.336 +                    smapper.assign(this, VarType.DOUBLE, lmapper.getD(0));
   1.337                      break;
   1.338                  case opc_aload_1:
   1.339 -                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(1));
   1.340 +                    smapper.assign(this, VarType.REFERENCE, lmapper.getA(1));
   1.341                      break;
   1.342                  case opc_iload_1:
   1.343 -                    smapper.assign(out, VarType.INTEGER, lmapper.getI(1));
   1.344 +                    smapper.assign(this, VarType.INTEGER, lmapper.getI(1));
   1.345                      break;
   1.346                  case opc_lload_1:
   1.347 -                    smapper.assign(out, VarType.LONG, lmapper.getL(1));
   1.348 +                    smapper.assign(this, VarType.LONG, lmapper.getL(1));
   1.349                      break;
   1.350                  case opc_fload_1:
   1.351 -                    smapper.assign(out, VarType.FLOAT, lmapper.getF(1));
   1.352 +                    smapper.assign(this, VarType.FLOAT, lmapper.getF(1));
   1.353                      break;
   1.354                  case opc_dload_1:
   1.355 -                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(1));
   1.356 +                    smapper.assign(this, VarType.DOUBLE, lmapper.getD(1));
   1.357                      break;
   1.358                  case opc_aload_2:
   1.359 -                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(2));
   1.360 +                    smapper.assign(this, VarType.REFERENCE, lmapper.getA(2));
   1.361                      break;
   1.362                  case opc_iload_2:
   1.363 -                    smapper.assign(out, VarType.INTEGER, lmapper.getI(2));
   1.364 +                    smapper.assign(this, VarType.INTEGER, lmapper.getI(2));
   1.365                      break;
   1.366                  case opc_lload_2:
   1.367 -                    smapper.assign(out, VarType.LONG, lmapper.getL(2));
   1.368 +                    smapper.assign(this, VarType.LONG, lmapper.getL(2));
   1.369                      break;
   1.370                  case opc_fload_2:
   1.371 -                    smapper.assign(out, VarType.FLOAT, lmapper.getF(2));
   1.372 +                    smapper.assign(this, VarType.FLOAT, lmapper.getF(2));
   1.373                      break;
   1.374                  case opc_dload_2:
   1.375 -                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(2));
   1.376 +                    smapper.assign(this, VarType.DOUBLE, lmapper.getD(2));
   1.377                      break;
   1.378                  case opc_aload_3:
   1.379 -                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(3));
   1.380 +                    smapper.assign(this, VarType.REFERENCE, lmapper.getA(3));
   1.381                      break;
   1.382                  case opc_iload_3:
   1.383 -                    smapper.assign(out, VarType.INTEGER, lmapper.getI(3));
   1.384 +                    smapper.assign(this, VarType.INTEGER, lmapper.getI(3));
   1.385                      break;
   1.386                  case opc_lload_3:
   1.387 -                    smapper.assign(out, VarType.LONG, lmapper.getL(3));
   1.388 +                    smapper.assign(this, VarType.LONG, lmapper.getL(3));
   1.389                      break;
   1.390                  case opc_fload_3:
   1.391 -                    smapper.assign(out, VarType.FLOAT, lmapper.getF(3));
   1.392 +                    smapper.assign(this, VarType.FLOAT, lmapper.getF(3));
   1.393                      break;
   1.394                  case opc_dload_3:
   1.395 -                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(3));
   1.396 +                    smapper.assign(this, VarType.DOUBLE, lmapper.getD(3));
   1.397                      break;
   1.398                  case opc_iload: {
   1.399                      ++i;
   1.400                      final int indx = wide ? readUShort(byteCodes, i++)
   1.401                                            : readUByte(byteCodes, i);
   1.402                      wide = false;
   1.403 -                    smapper.assign(out, VarType.INTEGER, lmapper.getI(indx));
   1.404 +                    smapper.assign(this, VarType.INTEGER, lmapper.getI(indx));
   1.405                      break;
   1.406                  }
   1.407                  case opc_lload: {
   1.408 @@ -453,7 +475,7 @@
   1.409                      final int indx = wide ? readUShort(byteCodes, i++)
   1.410                                            : readUByte(byteCodes, i);
   1.411                      wide = false;
   1.412 -                    smapper.assign(out, VarType.LONG, lmapper.getL(indx));
   1.413 +                    smapper.assign(this, VarType.LONG, lmapper.getL(indx));
   1.414                      break;
   1.415                  }
   1.416                  case opc_fload: {
   1.417 @@ -461,7 +483,7 @@
   1.418                      final int indx = wide ? readUShort(byteCodes, i++)
   1.419                                            : readUByte(byteCodes, i);
   1.420                      wide = false;
   1.421 -                    smapper.assign(out, VarType.FLOAT, lmapper.getF(indx));
   1.422 +                    smapper.assign(this, VarType.FLOAT, lmapper.getF(indx));
   1.423                      break;
   1.424                  }
   1.425                  case opc_dload: {
   1.426 @@ -469,7 +491,7 @@
   1.427                      final int indx = wide ? readUShort(byteCodes, i++)
   1.428                                            : readUByte(byteCodes, i);
   1.429                      wide = false;
   1.430 -                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(indx));
   1.431 +                    smapper.assign(this, VarType.DOUBLE, lmapper.getD(indx));
   1.432                      break;
   1.433                  }
   1.434                  case opc_aload: {
   1.435 @@ -477,7 +499,7 @@
   1.436                      final int indx = wide ? readUShort(byteCodes, i++)
   1.437                                            : readUByte(byteCodes, i);
   1.438                      wide = false;
   1.439 -                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(indx));
   1.440 +                    smapper.assign(this, VarType.REFERENCE, lmapper.getA(indx));
   1.441                      break;
   1.442                  }
   1.443                  case opc_istore: {
   1.444 @@ -485,7 +507,7 @@
   1.445                      final int indx = wide ? readUShort(byteCodes, i++)
   1.446                                            : readUByte(byteCodes, i);
   1.447                      wide = false;
   1.448 -                    emit(smapper, out, "var @1 = @2;",
   1.449 +                    emit(smapper, this, "var @1 = @2;",
   1.450                           lmapper.setI(indx), smapper.popI());
   1.451                      break;
   1.452                  }
   1.453 @@ -494,7 +516,7 @@
   1.454                      final int indx = wide ? readUShort(byteCodes, i++)
   1.455                                            : readUByte(byteCodes, i);
   1.456                      wide = false;
   1.457 -                    emit(smapper, out, "var @1 = @2;",
   1.458 +                    emit(smapper, this, "var @1 = @2;",
   1.459                           lmapper.setL(indx), smapper.popL());
   1.460                      break;
   1.461                  }
   1.462 @@ -503,7 +525,7 @@
   1.463                      final int indx = wide ? readUShort(byteCodes, i++)
   1.464                                            : readUByte(byteCodes, i);
   1.465                      wide = false;
   1.466 -                    emit(smapper, out, "var @1 = @2;",
   1.467 +                    emit(smapper, this, "var @1 = @2;",
   1.468                           lmapper.setF(indx), smapper.popF());
   1.469                      break;
   1.470                  }
   1.471 @@ -512,7 +534,7 @@
   1.472                      final int indx = wide ? readUShort(byteCodes, i++)
   1.473                                            : readUByte(byteCodes, i);
   1.474                      wide = false;
   1.475 -                    emit(smapper, out, "var @1 = @2;",
   1.476 +                    emit(smapper, this, "var @1 = @2;",
   1.477                           lmapper.setD(indx), smapper.popD());
   1.478                      break;
   1.479                  }
   1.480 @@ -521,181 +543,181 @@
   1.481                      final int indx = wide ? readUShort(byteCodes, i++)
   1.482                                            : readUByte(byteCodes, i);
   1.483                      wide = false;
   1.484 -                    emit(smapper, out, "var @1 = @2;",
   1.485 +                    emit(smapper, this, "var @1 = @2;",
   1.486                           lmapper.setA(indx), smapper.popA());
   1.487                      break;
   1.488                  }
   1.489                  case opc_astore_0:
   1.490 -                    emit(smapper, out, "var @1 = @2;", lmapper.setA(0), smapper.popA());
   1.491 +                    emit(smapper, this, "var @1 = @2;", lmapper.setA(0), smapper.popA());
   1.492                      break;
   1.493                  case opc_istore_0:
   1.494 -                    emit(smapper, out, "var @1 = @2;", lmapper.setI(0), smapper.popI());
   1.495 +                    emit(smapper, this, "var @1 = @2;", lmapper.setI(0), smapper.popI());
   1.496                      break;
   1.497                  case opc_lstore_0:
   1.498 -                    emit(smapper, out, "var @1 = @2;", lmapper.setL(0), smapper.popL());
   1.499 +                    emit(smapper, this, "var @1 = @2;", lmapper.setL(0), smapper.popL());
   1.500                      break;
   1.501                  case opc_fstore_0:
   1.502 -                    emit(smapper, out, "var @1 = @2;", lmapper.setF(0), smapper.popF());
   1.503 +                    emit(smapper, this, "var @1 = @2;", lmapper.setF(0), smapper.popF());
   1.504                      break;
   1.505                  case opc_dstore_0:
   1.506 -                    emit(smapper, out, "var @1 = @2;", lmapper.setD(0), smapper.popD());
   1.507 +                    emit(smapper, this, "var @1 = @2;", lmapper.setD(0), smapper.popD());
   1.508                      break;
   1.509                  case opc_astore_1:
   1.510 -                    emit(smapper, out, "var @1 = @2;", lmapper.setA(1), smapper.popA());
   1.511 +                    emit(smapper, this, "var @1 = @2;", lmapper.setA(1), smapper.popA());
   1.512                      break;
   1.513                  case opc_istore_1:
   1.514 -                    emit(smapper, out, "var @1 = @2;", lmapper.setI(1), smapper.popI());
   1.515 +                    emit(smapper, this, "var @1 = @2;", lmapper.setI(1), smapper.popI());
   1.516                      break;
   1.517                  case opc_lstore_1:
   1.518 -                    emit(smapper, out, "var @1 = @2;", lmapper.setL(1), smapper.popL());
   1.519 +                    emit(smapper, this, "var @1 = @2;", lmapper.setL(1), smapper.popL());
   1.520                      break;
   1.521                  case opc_fstore_1:
   1.522 -                    emit(smapper, out, "var @1 = @2;", lmapper.setF(1), smapper.popF());
   1.523 +                    emit(smapper, this, "var @1 = @2;", lmapper.setF(1), smapper.popF());
   1.524                      break;
   1.525                  case opc_dstore_1:
   1.526 -                    emit(smapper, out, "var @1 = @2;", lmapper.setD(1), smapper.popD());
   1.527 +                    emit(smapper, this, "var @1 = @2;", lmapper.setD(1), smapper.popD());
   1.528                      break;
   1.529                  case opc_astore_2:
   1.530 -                    emit(smapper, out, "var @1 = @2;", lmapper.setA(2), smapper.popA());
   1.531 +                    emit(smapper, this, "var @1 = @2;", lmapper.setA(2), smapper.popA());
   1.532                      break;
   1.533                  case opc_istore_2:
   1.534 -                    emit(smapper, out, "var @1 = @2;", lmapper.setI(2), smapper.popI());
   1.535 +                    emit(smapper, this, "var @1 = @2;", lmapper.setI(2), smapper.popI());
   1.536                      break;
   1.537                  case opc_lstore_2:
   1.538 -                    emit(smapper, out, "var @1 = @2;", lmapper.setL(2), smapper.popL());
   1.539 +                    emit(smapper, this, "var @1 = @2;", lmapper.setL(2), smapper.popL());
   1.540                      break;
   1.541                  case opc_fstore_2:
   1.542 -                    emit(smapper, out, "var @1 = @2;", lmapper.setF(2), smapper.popF());
   1.543 +                    emit(smapper, this, "var @1 = @2;", lmapper.setF(2), smapper.popF());
   1.544                      break;
   1.545                  case opc_dstore_2:
   1.546 -                    emit(smapper, out, "var @1 = @2;", lmapper.setD(2), smapper.popD());
   1.547 +                    emit(smapper, this, "var @1 = @2;", lmapper.setD(2), smapper.popD());
   1.548                      break;
   1.549                  case opc_astore_3:
   1.550 -                    emit(smapper, out, "var @1 = @2;", lmapper.setA(3), smapper.popA());
   1.551 +                    emit(smapper, this, "var @1 = @2;", lmapper.setA(3), smapper.popA());
   1.552                      break;
   1.553                  case opc_istore_3:
   1.554 -                    emit(smapper, out, "var @1 = @2;", lmapper.setI(3), smapper.popI());
   1.555 +                    emit(smapper, this, "var @1 = @2;", lmapper.setI(3), smapper.popI());
   1.556                      break;
   1.557                  case opc_lstore_3:
   1.558 -                    emit(smapper, out, "var @1 = @2;", lmapper.setL(3), smapper.popL());
   1.559 +                    emit(smapper, this, "var @1 = @2;", lmapper.setL(3), smapper.popL());
   1.560                      break;
   1.561                  case opc_fstore_3:
   1.562 -                    emit(smapper, out, "var @1 = @2;", lmapper.setF(3), smapper.popF());
   1.563 +                    emit(smapper, this, "var @1 = @2;", lmapper.setF(3), smapper.popF());
   1.564                      break;
   1.565                  case opc_dstore_3:
   1.566 -                    emit(smapper, out, "var @1 = @2;", lmapper.setD(3), smapper.popD());
   1.567 +                    emit(smapper, this, "var @1 = @2;", lmapper.setD(3), smapper.popD());
   1.568                      break;
   1.569                  case opc_iadd:
   1.570 -                    smapper.replace(out, VarType.INTEGER, "(@1).add32(@2)", smapper.getI(1), smapper.popI());
   1.571 +                    smapper.replace(this, VarType.INTEGER, "(@1).add32(@2)", smapper.getI(1), smapper.popI());
   1.572                      break;
   1.573                  case opc_ladd:
   1.574 -                    smapper.replace(out, VarType.LONG, "(@1).add64(@2)", smapper.getL(1), smapper.popL());
   1.575 +                    smapper.replace(this, VarType.LONG, "(@1).add64(@2)", smapper.getL(1), smapper.popL());
   1.576                      break;
   1.577                  case opc_fadd:
   1.578 -                    smapper.replace(out, VarType.FLOAT, "(@1 + @2)", smapper.getF(1), smapper.popF());
   1.579 +                    smapper.replace(this, VarType.FLOAT, "(@1 + @2)", smapper.getF(1), smapper.popF());
   1.580                      break;
   1.581                  case opc_dadd:
   1.582 -                    smapper.replace(out, VarType.DOUBLE, "(@1 + @2)", smapper.getD(1), smapper.popD());
   1.583 +                    smapper.replace(this, VarType.DOUBLE, "(@1 + @2)", smapper.getD(1), smapper.popD());
   1.584                      break;
   1.585                  case opc_isub:
   1.586 -                    smapper.replace(out, VarType.INTEGER, "(@1).sub32(@2)", smapper.getI(1), smapper.popI());
   1.587 +                    smapper.replace(this, VarType.INTEGER, "(@1).sub32(@2)", smapper.getI(1), smapper.popI());
   1.588                      break;
   1.589                  case opc_lsub:
   1.590 -                    smapper.replace(out, VarType.LONG, "(@1).sub64(@2)", smapper.getL(1), smapper.popL());
   1.591 +                    smapper.replace(this, VarType.LONG, "(@1).sub64(@2)", smapper.getL(1), smapper.popL());
   1.592                      break;
   1.593                  case opc_fsub:
   1.594 -                    smapper.replace(out, VarType.FLOAT, "(@1 - @2)", smapper.getF(1), smapper.popF());
   1.595 +                    smapper.replace(this, VarType.FLOAT, "(@1 - @2)", smapper.getF(1), smapper.popF());
   1.596                      break;
   1.597                  case opc_dsub:
   1.598 -                    smapper.replace(out, VarType.DOUBLE, "(@1 - @2)", smapper.getD(1), smapper.popD());
   1.599 +                    smapper.replace(this, VarType.DOUBLE, "(@1 - @2)", smapper.getD(1), smapper.popD());
   1.600                      break;
   1.601                  case opc_imul:
   1.602 -                    smapper.replace(out, VarType.INTEGER, "(@1).mul32(@2)", smapper.getI(1), smapper.popI());
   1.603 +                    smapper.replace(this, VarType.INTEGER, "(@1).mul32(@2)", smapper.getI(1), smapper.popI());
   1.604                      break;
   1.605                  case opc_lmul:
   1.606 -                    smapper.replace(out, VarType.LONG, "(@1).mul64(@2)", smapper.getL(1), smapper.popL());
   1.607 +                    smapper.replace(this, VarType.LONG, "(@1).mul64(@2)", smapper.getL(1), smapper.popL());
   1.608                      break;
   1.609                  case opc_fmul:
   1.610 -                    smapper.replace(out, VarType.FLOAT, "(@1 * @2)", smapper.getF(1), smapper.popF());
   1.611 +                    smapper.replace(this, VarType.FLOAT, "(@1 * @2)", smapper.getF(1), smapper.popF());
   1.612                      break;
   1.613                  case opc_dmul:
   1.614 -                    smapper.replace(out, VarType.DOUBLE, "(@1 * @2)", smapper.getD(1), smapper.popD());
   1.615 +                    smapper.replace(this, VarType.DOUBLE, "(@1 * @2)", smapper.getD(1), smapper.popD());
   1.616                      break;
   1.617                  case opc_idiv:
   1.618 -                    smapper.replace(out, VarType.INTEGER, "(@1).div32(@2)",
   1.619 +                    smapper.replace(this, VarType.INTEGER, "(@1).div32(@2)",
   1.620                           smapper.getI(1), smapper.popI());
   1.621                      break;
   1.622                  case opc_ldiv:
   1.623 -                    smapper.replace(out, VarType.LONG, "(@1).div64(@2)",
   1.624 +                    smapper.replace(this, VarType.LONG, "(@1).div64(@2)",
   1.625                           smapper.getL(1), smapper.popL());
   1.626                      break;
   1.627                  case opc_fdiv:
   1.628 -                    smapper.replace(out, VarType.FLOAT, "(@1 / @2)", smapper.getF(1), smapper.popF());
   1.629 +                    smapper.replace(this, VarType.FLOAT, "(@1 / @2)", smapper.getF(1), smapper.popF());
   1.630                      break;
   1.631                  case opc_ddiv:
   1.632 -                    smapper.replace(out, VarType.DOUBLE, "(@1 / @2)", smapper.getD(1), smapper.popD());
   1.633 +                    smapper.replace(this, VarType.DOUBLE, "(@1 / @2)", smapper.getD(1), smapper.popD());
   1.634                      break;
   1.635                  case opc_irem:
   1.636 -                    smapper.replace(out, VarType.INTEGER, "(@1).mod32(@2)",
   1.637 +                    smapper.replace(this, VarType.INTEGER, "(@1).mod32(@2)",
   1.638                           smapper.getI(1), smapper.popI());
   1.639                      break;
   1.640                  case opc_lrem:
   1.641 -                    smapper.replace(out, VarType.LONG, "(@1).mod64(@2)",
   1.642 +                    smapper.replace(this, VarType.LONG, "(@1).mod64(@2)",
   1.643                           smapper.getL(1), smapper.popL());
   1.644                      break;
   1.645                  case opc_frem:
   1.646 -                    smapper.replace(out, VarType.FLOAT, "(@1 % @2)", smapper.getF(1), smapper.popF());
   1.647 +                    smapper.replace(this, VarType.FLOAT, "(@1 % @2)", smapper.getF(1), smapper.popF());
   1.648                      break;
   1.649                  case opc_drem:
   1.650 -                    smapper.replace(out, VarType.DOUBLE, "(@1 % @2)", smapper.getD(1), smapper.popD());
   1.651 +                    smapper.replace(this, VarType.DOUBLE, "(@1 % @2)", smapper.getD(1), smapper.popD());
   1.652                      break;
   1.653                  case opc_iand:
   1.654 -                    smapper.replace(out, VarType.INTEGER, "(@1 & @2)", smapper.getI(1), smapper.popI());
   1.655 +                    smapper.replace(this, VarType.INTEGER, "(@1 & @2)", smapper.getI(1), smapper.popI());
   1.656                      break;
   1.657                  case opc_land:
   1.658 -                    smapper.replace(out, VarType.LONG, "(@1).and64(@2)", smapper.getL(1), smapper.popL());
   1.659 +                    smapper.replace(this, VarType.LONG, "(@1).and64(@2)", smapper.getL(1), smapper.popL());
   1.660                      break;
   1.661                  case opc_ior:
   1.662 -                    smapper.replace(out, VarType.INTEGER, "(@1 | @2)", smapper.getI(1), smapper.popI());
   1.663 +                    smapper.replace(this, VarType.INTEGER, "(@1 | @2)", smapper.getI(1), smapper.popI());
   1.664                      break;
   1.665                  case opc_lor:
   1.666 -                    smapper.replace(out, VarType.LONG, "(@1).or64(@2)", smapper.getL(1), smapper.popL());
   1.667 +                    smapper.replace(this, VarType.LONG, "(@1).or64(@2)", smapper.getL(1), smapper.popL());
   1.668                      break;
   1.669                  case opc_ixor:
   1.670 -                    smapper.replace(out, VarType.INTEGER, "(@1 ^ @2)", smapper.getI(1), smapper.popI());
   1.671 +                    smapper.replace(this, VarType.INTEGER, "(@1 ^ @2)", smapper.getI(1), smapper.popI());
   1.672                      break;
   1.673                  case opc_lxor:
   1.674 -                    smapper.replace(out, VarType.LONG, "(@1).xor64(@2)", smapper.getL(1), smapper.popL());
   1.675 +                    smapper.replace(this, VarType.LONG, "(@1).xor64(@2)", smapper.getL(1), smapper.popL());
   1.676                      break;
   1.677                  case opc_ineg:
   1.678 -                    smapper.replace(out, VarType.INTEGER, "(@1).neg32()", smapper.getI(0));
   1.679 +                    smapper.replace(this, VarType.INTEGER, "(@1).neg32()", smapper.getI(0));
   1.680                      break;
   1.681                  case opc_lneg:
   1.682 -                    smapper.replace(out, VarType.LONG, "(@1).neg64()", smapper.getL(0));
   1.683 +                    smapper.replace(this, VarType.LONG, "(@1).neg64()", smapper.getL(0));
   1.684                      break;
   1.685                  case opc_fneg:
   1.686 -                    smapper.replace(out, VarType.FLOAT, "(-@1)", smapper.getF(0));
   1.687 +                    smapper.replace(this, VarType.FLOAT, "(-@1)", smapper.getF(0));
   1.688                      break;
   1.689                  case opc_dneg:
   1.690 -                    smapper.replace(out, VarType.DOUBLE, "(-@1)", smapper.getD(0));
   1.691 +                    smapper.replace(this, VarType.DOUBLE, "(-@1)", smapper.getD(0));
   1.692                      break;
   1.693                  case opc_ishl:
   1.694 -                    smapper.replace(out, VarType.INTEGER, "(@1 << @2)", smapper.getI(1), smapper.popI());
   1.695 +                    smapper.replace(this, VarType.INTEGER, "(@1 << @2)", smapper.getI(1), smapper.popI());
   1.696                      break;
   1.697                  case opc_lshl:
   1.698 -                    smapper.replace(out, VarType.LONG, "(@1).shl64(@2)", smapper.getL(1), smapper.popI());
   1.699 +                    smapper.replace(this, VarType.LONG, "(@1).shl64(@2)", smapper.getL(1), smapper.popI());
   1.700                      break;
   1.701                  case opc_ishr:
   1.702 -                    smapper.replace(out, VarType.INTEGER, "(@1 >> @2)", smapper.getI(1), smapper.popI());
   1.703 +                    smapper.replace(this, VarType.INTEGER, "(@1 >> @2)", smapper.getI(1), smapper.popI());
   1.704                      break;
   1.705                  case opc_lshr:
   1.706 -                    smapper.replace(out, VarType.LONG, "(@1).shr64(@2)", smapper.getL(1), smapper.popI());
   1.707 +                    smapper.replace(this, VarType.LONG, "(@1).shr64(@2)", smapper.getL(1), smapper.popI());
   1.708                      break;
   1.709                  case opc_iushr:
   1.710 -                    smapper.replace(out, VarType.INTEGER, "(@1 >>> @2)", smapper.getI(1), smapper.popI());
   1.711 +                    smapper.replace(this, VarType.INTEGER, "(@1 >>> @2)", smapper.getI(1), smapper.popI());
   1.712                      break;
   1.713                  case opc_lushr:
   1.714 -                    smapper.replace(out, VarType.LONG, "(@1).ushr64(@2)", smapper.getL(1), smapper.popI());
   1.715 +                    smapper.replace(this, VarType.LONG, "(@1).ushr64(@2)", smapper.getL(1), smapper.popI());
   1.716                      break;
   1.717                  case opc_iinc: {
   1.718                      ++i;
   1.719 @@ -706,132 +728,132 @@
   1.720                                              : byteCodes[i];
   1.721                      wide = false;
   1.722                      if (incrBy == 1) {
   1.723 -                        emit(smapper, out, "@1++;", lmapper.getI(varIndx));
   1.724 +                        emit(smapper, this, "@1++;", lmapper.getI(varIndx));
   1.725                      } else {
   1.726 -                        emit(smapper, out, "@1 += @2;",
   1.727 +                        emit(smapper, this, "@1 += @2;",
   1.728                               lmapper.getI(varIndx),
   1.729                               Integer.toString(incrBy));
   1.730                      }
   1.731                      break;
   1.732                  }
   1.733                  case opc_return:
   1.734 -                    emit(smapper, out, "return;");
   1.735 +                    emit(smapper, this, "return;");
   1.736                      break;
   1.737                  case opc_ireturn:
   1.738 -                    emit(smapper, out, "return @1;", smapper.popI());
   1.739 +                    emit(smapper, this, "return @1;", smapper.popI());
   1.740                      break;
   1.741                  case opc_lreturn:
   1.742 -                    emit(smapper, out, "return @1;", smapper.popL());
   1.743 +                    emit(smapper, this, "return @1;", smapper.popL());
   1.744                      break;
   1.745                  case opc_freturn:
   1.746 -                    emit(smapper, out, "return @1;", smapper.popF());
   1.747 +                    emit(smapper, this, "return @1;", smapper.popF());
   1.748                      break;
   1.749                  case opc_dreturn:
   1.750 -                    emit(smapper, out, "return @1;", smapper.popD());
   1.751 +                    emit(smapper, this, "return @1;", smapper.popD());
   1.752                      break;
   1.753                  case opc_areturn:
   1.754 -                    emit(smapper, out, "return @1;", smapper.popA());
   1.755 +                    emit(smapper, this, "return @1;", smapper.popA());
   1.756                      break;
   1.757                  case opc_i2l:
   1.758 -                    smapper.replace(out, VarType.LONG, "@1", smapper.getI(0));
   1.759 +                    smapper.replace(this, VarType.LONG, "@1", smapper.getI(0));
   1.760                      break;
   1.761                  case opc_i2f:
   1.762 -                    smapper.replace(out, VarType.FLOAT, "@1", smapper.getI(0));
   1.763 +                    smapper.replace(this, VarType.FLOAT, "@1", smapper.getI(0));
   1.764                      break;
   1.765                  case opc_i2d:
   1.766 -                    smapper.replace(out, VarType.DOUBLE, "@1", smapper.getI(0));
   1.767 +                    smapper.replace(this, VarType.DOUBLE, "@1", smapper.getI(0));
   1.768                      break;
   1.769                  case opc_l2i:
   1.770 -                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()", smapper.getL(0));
   1.771 +                    smapper.replace(this, VarType.INTEGER, "(@1).toInt32()", smapper.getL(0));
   1.772                      break;
   1.773                      // max int check?
   1.774                  case opc_l2f:
   1.775 -                    smapper.replace(out, VarType.FLOAT, "(@1).toFP()", smapper.getL(0));
   1.776 +                    smapper.replace(this, VarType.FLOAT, "(@1).toFP()", smapper.getL(0));
   1.777                      break;
   1.778                  case opc_l2d:
   1.779 -                    smapper.replace(out, VarType.DOUBLE, "(@1).toFP()", smapper.getL(0));
   1.780 +                    smapper.replace(this, VarType.DOUBLE, "(@1).toFP()", smapper.getL(0));
   1.781                      break;
   1.782                  case opc_f2d:
   1.783 -                    smapper.replace(out, VarType.DOUBLE, "@1",
   1.784 +                    smapper.replace(this, VarType.DOUBLE, "@1",
   1.785                           smapper.getF(0));
   1.786                      break;
   1.787                  case opc_d2f:
   1.788 -                    smapper.replace(out, VarType.FLOAT, "@1",
   1.789 +                    smapper.replace(this, VarType.FLOAT, "@1",
   1.790                           smapper.getD(0));
   1.791                      break;
   1.792                  case opc_f2i:
   1.793 -                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()",
   1.794 +                    smapper.replace(this, VarType.INTEGER, "(@1).toInt32()",
   1.795                           smapper.getF(0));
   1.796                      break;
   1.797                  case opc_f2l:
   1.798 -                    smapper.replace(out, VarType.LONG, "(@1).toLong()",
   1.799 +                    smapper.replace(this, VarType.LONG, "(@1).toLong()",
   1.800                           smapper.getF(0));
   1.801                      break;
   1.802                  case opc_d2i:
   1.803 -                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()",
   1.804 +                    smapper.replace(this, VarType.INTEGER, "(@1).toInt32()",
   1.805                           smapper.getD(0));
   1.806                      break;
   1.807                  case opc_d2l:
   1.808 -                    smapper.replace(out, VarType.LONG, "(@1).toLong()", smapper.getD(0));
   1.809 +                    smapper.replace(this, VarType.LONG, "(@1).toLong()", smapper.getD(0));
   1.810                      break;
   1.811                  case opc_i2b:
   1.812 -                    smapper.replace(out, VarType.INTEGER, "(@1).toInt8()", smapper.getI(0));
   1.813 +                    smapper.replace(this, VarType.INTEGER, "(@1).toInt8()", smapper.getI(0));
   1.814                      break;
   1.815                  case opc_i2c:
   1.816                      break;
   1.817                  case opc_i2s:
   1.818 -                    smapper.replace(out, VarType.INTEGER, "(@1).toInt16()", smapper.getI(0));
   1.819 +                    smapper.replace(this, VarType.INTEGER, "(@1).toInt16()", smapper.getI(0));
   1.820                      break;
   1.821                  case opc_aconst_null:
   1.822 -                    smapper.assign(out, VarType.REFERENCE, "null");
   1.823 +                    smapper.assign(this, VarType.REFERENCE, "null");
   1.824                      break;
   1.825                  case opc_iconst_m1:
   1.826 -                    smapper.assign(out, VarType.INTEGER, "-1");
   1.827 +                    smapper.assign(this, VarType.INTEGER, "-1");
   1.828                      break;
   1.829                  case opc_iconst_0:
   1.830 -                    smapper.assign(out, VarType.INTEGER, "0");
   1.831 +                    smapper.assign(this, VarType.INTEGER, "0");
   1.832                      break;
   1.833                  case opc_dconst_0:
   1.834 -                    smapper.assign(out, VarType.DOUBLE, "0");
   1.835 +                    smapper.assign(this, VarType.DOUBLE, "0");
   1.836                      break;
   1.837                  case opc_lconst_0:
   1.838 -                    smapper.assign(out, VarType.LONG, "0");
   1.839 +                    smapper.assign(this, VarType.LONG, "0");
   1.840                      break;
   1.841                  case opc_fconst_0:
   1.842 -                    smapper.assign(out, VarType.FLOAT, "0");
   1.843 +                    smapper.assign(this, VarType.FLOAT, "0");
   1.844                      break;
   1.845                  case opc_iconst_1:
   1.846 -                    smapper.assign(out, VarType.INTEGER, "1");
   1.847 +                    smapper.assign(this, VarType.INTEGER, "1");
   1.848                      break;
   1.849                  case opc_lconst_1:
   1.850 -                    smapper.assign(out, VarType.LONG, "1");
   1.851 +                    smapper.assign(this, VarType.LONG, "1");
   1.852                      break;
   1.853                  case opc_fconst_1:
   1.854 -                    smapper.assign(out, VarType.FLOAT, "1");
   1.855 +                    smapper.assign(this, VarType.FLOAT, "1");
   1.856                      break;
   1.857                  case opc_dconst_1:
   1.858 -                    smapper.assign(out, VarType.DOUBLE, "1");
   1.859 +                    smapper.assign(this, VarType.DOUBLE, "1");
   1.860                      break;
   1.861                  case opc_iconst_2:
   1.862 -                    smapper.assign(out, VarType.INTEGER, "2");
   1.863 +                    smapper.assign(this, VarType.INTEGER, "2");
   1.864                      break;
   1.865                  case opc_fconst_2:
   1.866 -                    smapper.assign(out, VarType.FLOAT, "2");
   1.867 +                    smapper.assign(this, VarType.FLOAT, "2");
   1.868                      break;
   1.869                  case opc_iconst_3:
   1.870 -                    smapper.assign(out, VarType.INTEGER, "3");
   1.871 +                    smapper.assign(this, VarType.INTEGER, "3");
   1.872                      break;
   1.873                  case opc_iconst_4:
   1.874 -                    smapper.assign(out, VarType.INTEGER, "4");
   1.875 +                    smapper.assign(this, VarType.INTEGER, "4");
   1.876                      break;
   1.877                  case opc_iconst_5:
   1.878 -                    smapper.assign(out, VarType.INTEGER, "5");
   1.879 +                    smapper.assign(this, VarType.INTEGER, "5");
   1.880                      break;
   1.881                  case opc_ldc: {
   1.882                      int indx = readUByte(byteCodes, ++i);
   1.883                      String v = encodeConstant(indx);
   1.884                      int type = VarType.fromConstantType(jc.getTag(indx));
   1.885 -                    smapper.assign(out, type, v);
   1.886 +                    smapper.assign(this, type, v);
   1.887                      break;
   1.888                  }
   1.889                  case opc_ldc_w:
   1.890 @@ -845,28 +867,28 @@
   1.891                          final int low = (int)(lv.longValue() & 0xFFFFFFFF);
   1.892                          final int hi = (int)(lv.longValue() >> 32);
   1.893                          if (hi == 0) {
   1.894 -                            smapper.assign(out, VarType.LONG, "0x" + Integer.toHexString(low));
   1.895 +                            smapper.assign(this, VarType.LONG, "0x" + Integer.toHexString(low));
   1.896                          } else {
   1.897 -                            smapper.assign(out, VarType.LONG,
   1.898 +                            smapper.assign(this, VarType.LONG,
   1.899                                  "0x" + Integer.toHexString(hi) + ".next32(0x" + 
   1.900                                      Integer.toHexString(low) + ")"
   1.901                              );
   1.902                          }
   1.903                      } else {
   1.904 -                        smapper.assign(out, type, v);
   1.905 +                        smapper.assign(this, type, v);
   1.906                      }
   1.907                      break;
   1.908                  }
   1.909                  case opc_lcmp:
   1.910 -                    smapper.replace(out, VarType.INTEGER, "(@2).compare64(@1)", smapper.popL(), smapper.getL(0));
   1.911 +                    smapper.replace(this, VarType.INTEGER, "(@2).compare64(@1)", smapper.popL(), smapper.getL(0));
   1.912                      break;
   1.913                  case opc_fcmpl:
   1.914                  case opc_fcmpg:
   1.915 -                    smapper.replace(out, VarType.INTEGER, "(@2).compare(@1)", smapper.popF(), smapper.getF(0));
   1.916 +                    smapper.replace(this, VarType.INTEGER, "(@2).compare(@1)", smapper.popF(), smapper.getF(0));
   1.917                      break;
   1.918                  case opc_dcmpl:
   1.919                  case opc_dcmpg:
   1.920 -                    smapper.replace(out, VarType.INTEGER, "(@2).compare(@1)", smapper.popD(), smapper.getD(0));
   1.921 +                    smapper.replace(this, VarType.INTEGER, "(@2).compare(@1)", smapper.popD(), smapper.getD(0));
   1.922                      break;
   1.923                  case opc_if_acmpeq:
   1.924                      i = generateIf(smapper, byteCodes, i, smapper.popA(), smapper.popA(),
   1.925 @@ -882,56 +904,56 @@
   1.926                      break;
   1.927                  case opc_ifeq: {
   1.928                      int indx = i + readShortArg(byteCodes, i);
   1.929 -                    emitIf(smapper, out, "if ((@1) == 0) ",
   1.930 +                    emitIf(smapper, this, "if ((@1) == 0) ",
   1.931                           smapper.popI(), i, indx, topMostLabel);
   1.932                      i += 2;
   1.933                      break;
   1.934                  }
   1.935                  case opc_ifne: {
   1.936                      int indx = i + readShortArg(byteCodes, i);
   1.937 -                    emitIf(smapper, out, "if ((@1) != 0) ",
   1.938 +                    emitIf(smapper, this, "if ((@1) != 0) ",
   1.939                           smapper.popI(), i, indx, topMostLabel);
   1.940                      i += 2;
   1.941                      break;
   1.942                  }
   1.943                  case opc_iflt: {
   1.944                      int indx = i + readShortArg(byteCodes, i);
   1.945 -                    emitIf(smapper, out, "if ((@1) < 0) ",
   1.946 +                    emitIf(smapper, this, "if ((@1) < 0) ",
   1.947                           smapper.popI(), i, indx, topMostLabel);
   1.948                      i += 2;
   1.949                      break;
   1.950                  }
   1.951                  case opc_ifle: {
   1.952                      int indx = i + readShortArg(byteCodes, i);
   1.953 -                    emitIf(smapper, out, "if ((@1) <= 0) ",
   1.954 +                    emitIf(smapper, this, "if ((@1) <= 0) ",
   1.955                           smapper.popI(), i, indx, topMostLabel);
   1.956                      i += 2;
   1.957                      break;
   1.958                  }
   1.959                  case opc_ifgt: {
   1.960                      int indx = i + readShortArg(byteCodes, i);
   1.961 -                    emitIf(smapper, out, "if ((@1) > 0) ",
   1.962 +                    emitIf(smapper, this, "if ((@1) > 0) ",
   1.963                           smapper.popI(), i, indx, topMostLabel);
   1.964                      i += 2;
   1.965                      break;
   1.966                  }
   1.967                  case opc_ifge: {
   1.968                      int indx = i + readShortArg(byteCodes, i);
   1.969 -                    emitIf(smapper, out, "if ((@1) >= 0) ",
   1.970 +                    emitIf(smapper, this, "if ((@1) >= 0) ",
   1.971                           smapper.popI(), i, indx, topMostLabel);
   1.972                      i += 2;
   1.973                      break;
   1.974                  }
   1.975                  case opc_ifnonnull: {
   1.976                      int indx = i + readShortArg(byteCodes, i);
   1.977 -                    emitIf(smapper, out, "if ((@1) !== null) ",
   1.978 +                    emitIf(smapper, this, "if ((@1) !== null) ",
   1.979                           smapper.popA(), i, indx, topMostLabel);
   1.980                      i += 2;
   1.981                      break;
   1.982                  }
   1.983                  case opc_ifnull: {
   1.984                      int indx = i + readShortArg(byteCodes, i);
   1.985 -                    emitIf(smapper, out, "if ((@1) === null) ",
   1.986 +                    emitIf(smapper, this, "if ((@1) === null) ",
   1.987                           smapper.popA(), i, indx, topMostLabel);
   1.988                      i += 2;
   1.989                      break;
   1.990 @@ -957,9 +979,9 @@
   1.991                                     ">=", topMostLabel);
   1.992                      break;
   1.993                  case opc_goto: {
   1.994 -                    smapper.flush(out);
   1.995 +                    smapper.flush(this);
   1.996                      int indx = i + readShortArg(byteCodes, i);
   1.997 -                    goTo(out, i, indx, topMostLabel);
   1.998 +                    goTo(this, i, indx, topMostLabel);
   1.999                      i += 2;
  1.1000                      break;
  1.1001                  }
  1.1002 @@ -987,7 +1009,7 @@
  1.1003                  case opc_new: {
  1.1004                      int indx = readUShortArg(byteCodes, i);
  1.1005                      String ci = jc.getClassName(indx);
  1.1006 -                    emit(smapper, out, "var @1 = new @2;",
  1.1007 +                    emit(smapper, this, "var @1 = new @2;",
  1.1008                           smapper.pushA(), accessClass(mangleClassName(ci)));
  1.1009                      addReference(ci);
  1.1010                      i += 2;
  1.1011 @@ -1010,52 +1032,52 @@
  1.1012                      break;
  1.1013                  }
  1.1014                  case opc_arraylength:
  1.1015 -                    smapper.replace(out, VarType.INTEGER, "(@1).length", smapper.getA(0));
  1.1016 +                    smapper.replace(this, VarType.INTEGER, "(@1).length", smapper.getA(0));
  1.1017                      break;
  1.1018                  case opc_lastore:
  1.1019 -                    emit(smapper, out, "Array.at(@3, @2, @1);",
  1.1020 +                    emit(smapper, this, "Array.at(@3, @2, @1);",
  1.1021                           smapper.popL(), smapper.popI(), smapper.popA());
  1.1022                      break;
  1.1023                  case opc_fastore:
  1.1024 -                    emit(smapper, out, "Array.at(@3, @2, @1);",
  1.1025 +                    emit(smapper, this, "Array.at(@3, @2, @1);",
  1.1026                           smapper.popF(), smapper.popI(), smapper.popA());
  1.1027                      break;
  1.1028                  case opc_dastore:
  1.1029 -                    emit(smapper, out, "Array.at(@3, @2, @1);",
  1.1030 +                    emit(smapper, this, "Array.at(@3, @2, @1);",
  1.1031                           smapper.popD(), smapper.popI(), smapper.popA());
  1.1032                      break;
  1.1033                  case opc_aastore:
  1.1034 -                    emit(smapper, out, "Array.at(@3, @2, @1);",
  1.1035 +                    emit(smapper, this, "Array.at(@3, @2, @1);",
  1.1036                           smapper.popA(), smapper.popI(), smapper.popA());
  1.1037                      break;
  1.1038                  case opc_iastore:
  1.1039                  case opc_bastore:
  1.1040                  case opc_castore:
  1.1041                  case opc_sastore:
  1.1042 -                    emit(smapper, out, "Array.at(@3, @2, @1);",
  1.1043 +                    emit(smapper, this, "Array.at(@3, @2, @1);",
  1.1044                           smapper.popI(), smapper.popI(), smapper.popA());
  1.1045                      break;
  1.1046                  case opc_laload:
  1.1047 -                    smapper.replace(out, VarType.LONG, "Array.at(@2, @1)",
  1.1048 +                    smapper.replace(this, VarType.LONG, "Array.at(@2, @1)",
  1.1049                           smapper.popI(), smapper.getA(0));
  1.1050                      break;
  1.1051                  case opc_faload:
  1.1052 -                    smapper.replace(out, VarType.FLOAT, "Array.at(@2, @1)",
  1.1053 +                    smapper.replace(this, VarType.FLOAT, "Array.at(@2, @1)",
  1.1054                           smapper.popI(), smapper.getA(0));
  1.1055                      break;
  1.1056                  case opc_daload:
  1.1057 -                    smapper.replace(out, VarType.DOUBLE, "Array.at(@2, @1)",
  1.1058 +                    smapper.replace(this, VarType.DOUBLE, "Array.at(@2, @1)",
  1.1059                           smapper.popI(), smapper.getA(0));
  1.1060                      break;
  1.1061                  case opc_aaload:
  1.1062 -                    smapper.replace(out, VarType.REFERENCE, "Array.at(@2, @1)",
  1.1063 +                    smapper.replace(this, VarType.REFERENCE, "Array.at(@2, @1)",
  1.1064                           smapper.popI(), smapper.getA(0));
  1.1065                      break;
  1.1066                  case opc_iaload:
  1.1067                  case opc_baload:
  1.1068                  case opc_caload:
  1.1069                  case opc_saload:
  1.1070 -                    smapper.replace(out, VarType.INTEGER, "Array.at(@2, @1)",
  1.1071 +                    smapper.replace(this, VarType.INTEGER, "Array.at(@2, @1)",
  1.1072                           smapper.popI(), smapper.getA(0));
  1.1073                      break;
  1.1074                  case opc_pop:
  1.1075 @@ -1065,86 +1087,86 @@
  1.1076                      break;
  1.1077                  case opc_dup: {
  1.1078                      final Variable v = smapper.get(0);
  1.1079 -                    emit(smapper, out, "var @1 = @2;", smapper.pushT(v.getType()), v);
  1.1080 +                    emit(smapper, this, "var @1 = @2;", smapper.pushT(v.getType()), v);
  1.1081                      break;
  1.1082                  }
  1.1083                  case opc_dup2: {
  1.1084                      final Variable vi1 = smapper.get(0);
  1.1085  
  1.1086                      if (vi1.isCategory2()) {
  1.1087 -                        emit(smapper, out, "var @1 = @2;",
  1.1088 +                        emit(smapper, this, "var @1 = @2;",
  1.1089                               smapper.pushT(vi1.getType()), vi1);
  1.1090                      } else {
  1.1091                          final Variable vi2 = smapper.get(1);
  1.1092 -                        emit(smapper, out, "var @1 = @2, @3 = @4;",
  1.1093 +                        emit(smapper, this, "var @1 = @2, @3 = @4;",
  1.1094                               smapper.pushT(vi2.getType()), vi2,
  1.1095                               smapper.pushT(vi1.getType()), vi1);
  1.1096                      }
  1.1097                      break;
  1.1098                  }
  1.1099                  case opc_dup_x1: {
  1.1100 -                    final Variable vi1 = smapper.pop(out);
  1.1101 -                    final Variable vi2 = smapper.pop(out);
  1.1102 +                    final Variable vi1 = smapper.pop(this);
  1.1103 +                    final Variable vi2 = smapper.pop(this);
  1.1104                      final Variable vo3 = smapper.pushT(vi1.getType());
  1.1105                      final Variable vo2 = smapper.pushT(vi2.getType());
  1.1106                      final Variable vo1 = smapper.pushT(vi1.getType());
  1.1107  
  1.1108 -                    emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1109 +                    emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1110                           vo1, vi1, vo2, vi2, vo3, vo1);
  1.1111                      break;
  1.1112                  }
  1.1113                  case opc_dup2_x1: {
  1.1114 -                    final Variable vi1 = smapper.pop(out);
  1.1115 -                    final Variable vi2 = smapper.pop(out);
  1.1116 +                    final Variable vi1 = smapper.pop(this);
  1.1117 +                    final Variable vi2 = smapper.pop(this);
  1.1118  
  1.1119                      if (vi1.isCategory2()) {
  1.1120                          final Variable vo3 = smapper.pushT(vi1.getType());
  1.1121                          final Variable vo2 = smapper.pushT(vi2.getType());
  1.1122                          final Variable vo1 = smapper.pushT(vi1.getType());
  1.1123  
  1.1124 -                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1125 +                        emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1126                               vo1, vi1, vo2, vi2, vo3, vo1);
  1.1127                      } else {
  1.1128 -                        final Variable vi3 = smapper.pop(out);
  1.1129 +                        final Variable vi3 = smapper.pop(this);
  1.1130                          final Variable vo5 = smapper.pushT(vi2.getType());
  1.1131                          final Variable vo4 = smapper.pushT(vi1.getType());
  1.1132                          final Variable vo3 = smapper.pushT(vi3.getType());
  1.1133                          final Variable vo2 = smapper.pushT(vi2.getType());
  1.1134                          final Variable vo1 = smapper.pushT(vi1.getType());
  1.1135  
  1.1136 -                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6,",
  1.1137 +                        emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6,",
  1.1138                               vo1, vi1, vo2, vi2, vo3, vi3);
  1.1139 -                        emit(smapper, out, " @1 = @2, @3 = @4;",
  1.1140 +                        emit(smapper, this, " @1 = @2, @3 = @4;",
  1.1141                               vo4, vo1, vo5, vo2);
  1.1142                      }
  1.1143                      break;
  1.1144                  }
  1.1145                  case opc_dup_x2: {
  1.1146 -                    final Variable vi1 = smapper.pop(out);
  1.1147 -                    final Variable vi2 = smapper.pop(out);
  1.1148 +                    final Variable vi1 = smapper.pop(this);
  1.1149 +                    final Variable vi2 = smapper.pop(this);
  1.1150  
  1.1151                      if (vi2.isCategory2()) {
  1.1152                          final Variable vo3 = smapper.pushT(vi1.getType());
  1.1153                          final Variable vo2 = smapper.pushT(vi2.getType());
  1.1154                          final Variable vo1 = smapper.pushT(vi1.getType());
  1.1155  
  1.1156 -                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1157 +                        emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1158                               vo1, vi1, vo2, vi2, vo3, vo1);
  1.1159                      } else {
  1.1160 -                        final Variable vi3 = smapper.pop(out);
  1.1161 +                        final Variable vi3 = smapper.pop(this);
  1.1162                          final Variable vo4 = smapper.pushT(vi1.getType());
  1.1163                          final Variable vo3 = smapper.pushT(vi3.getType());
  1.1164                          final Variable vo2 = smapper.pushT(vi2.getType());
  1.1165                          final Variable vo1 = smapper.pushT(vi1.getType());
  1.1166  
  1.1167 -                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
  1.1168 +                        emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
  1.1169                               vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
  1.1170                      }
  1.1171                      break;
  1.1172                  }
  1.1173                  case opc_dup2_x2: {
  1.1174 -                    final Variable vi1 = smapper.pop(out);
  1.1175 -                    final Variable vi2 = smapper.pop(out);
  1.1176 +                    final Variable vi1 = smapper.pop(this);
  1.1177 +                    final Variable vi2 = smapper.pop(this);
  1.1178  
  1.1179                      if (vi1.isCategory2()) {
  1.1180                          if (vi2.isCategory2()) {
  1.1181 @@ -1152,20 +1174,20 @@
  1.1182                              final Variable vo2 = smapper.pushT(vi2.getType());
  1.1183                              final Variable vo1 = smapper.pushT(vi1.getType());
  1.1184  
  1.1185 -                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1186 +                            emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6;",
  1.1187                                   vo1, vi1, vo2, vi2, vo3, vo1);
  1.1188                          } else {
  1.1189 -                            final Variable vi3 = smapper.pop(out);
  1.1190 +                            final Variable vi3 = smapper.pop(this);
  1.1191                              final Variable vo4 = smapper.pushT(vi1.getType());
  1.1192                              final Variable vo3 = smapper.pushT(vi3.getType());
  1.1193                              final Variable vo2 = smapper.pushT(vi2.getType());
  1.1194                              final Variable vo1 = smapper.pushT(vi1.getType());
  1.1195  
  1.1196 -                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
  1.1197 +                            emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
  1.1198                                   vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
  1.1199                          }
  1.1200                      } else {
  1.1201 -                        final Variable vi3 = smapper.pop(out);
  1.1202 +                        final Variable vi3 = smapper.pop(this);
  1.1203  
  1.1204                          if (vi3.isCategory2()) {
  1.1205                              final Variable vo5 = smapper.pushT(vi2.getType());
  1.1206 @@ -1174,12 +1196,12 @@
  1.1207                              final Variable vo2 = smapper.pushT(vi2.getType());
  1.1208                              final Variable vo1 = smapper.pushT(vi1.getType());
  1.1209  
  1.1210 -                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6,",
  1.1211 +                            emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6,",
  1.1212                                   vo1, vi1, vo2, vi2, vo3, vi3);
  1.1213 -                            emit(smapper, out, " @1 = @2, @3 = @4;",
  1.1214 +                            emit(smapper, this, " @1 = @2, @3 = @4;",
  1.1215                                   vo4, vo1, vo5, vo2);
  1.1216                          } else {
  1.1217 -                            final Variable vi4 = smapper.pop(out);
  1.1218 +                            final Variable vi4 = smapper.pop(this);
  1.1219                              final Variable vo6 = smapper.pushT(vi2.getType());
  1.1220                              final Variable vo5 = smapper.pushT(vi1.getType());
  1.1221                              final Variable vo4 = smapper.pushT(vi4.getType());
  1.1222 @@ -1187,9 +1209,9 @@
  1.1223                              final Variable vo2 = smapper.pushT(vi2.getType());
  1.1224                              final Variable vo1 = smapper.pushT(vi1.getType());
  1.1225                              
  1.1226 -                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8,",
  1.1227 +                            emit(smapper, this, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8,",
  1.1228                                   vo1, vi1, vo2, vi2, vo3, vi3, vo4, vi4);
  1.1229 -                            emit(smapper, out, " @1 = @2, @3 = @4;",
  1.1230 +                            emit(smapper, this, " @1 = @2, @3 = @4;",
  1.1231                                   vo5, vo1, vo6, vo2);
  1.1232                          }
  1.1233                      }
  1.1234 @@ -1202,7 +1224,7 @@
  1.1235                      if (vi1.getType() == vi2.getType()) {
  1.1236                          final Variable tmp = smapper.pushT(vi1.getType());
  1.1237  
  1.1238 -                        emit(smapper, out, "var @1 = @2, @2 = @3, @3 = @1;",
  1.1239 +                        emit(smapper, this, "var @1 = @2, @2 = @3, @3 = @1;",
  1.1240                               tmp, vi1, vi2);
  1.1241                          smapper.pop(1);
  1.1242                      } else {
  1.1243 @@ -1213,11 +1235,11 @@
  1.1244                      break;
  1.1245                  }
  1.1246                  case opc_bipush:
  1.1247 -                    smapper.assign(out, VarType.INTEGER, 
  1.1248 +                    smapper.assign(this, VarType.INTEGER, 
  1.1249                          "(" + Integer.toString(byteCodes[++i]) + ")");
  1.1250                      break;
  1.1251                  case opc_sipush:
  1.1252 -                    smapper.assign(out, VarType.INTEGER, 
  1.1253 +                    smapper.assign(this, VarType.INTEGER, 
  1.1254                          "(" + Integer.toString(readShortArg(byteCodes, i)) + ")"
  1.1255                      );
  1.1256                      i += 2;
  1.1257 @@ -1228,7 +1250,7 @@
  1.1258                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  1.1259                      final String mangleClass = mangleClassName(fi[0]);
  1.1260                      final String mangleClassAccess = accessClass(mangleClass);
  1.1261 -                    smapper.replace(out, type, "@3(false)._@2.call(@1)",
  1.1262 +                    smapper.replace(this, type, "@3(false)._@2.call(@1)",
  1.1263                           smapper.getA(0),
  1.1264                           fi[1], mangleClassAccess
  1.1265                      );
  1.1266 @@ -1241,7 +1263,7 @@
  1.1267                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  1.1268                      final String mangleClass = mangleClassName(fi[0]);
  1.1269                      final String mangleClassAccess = accessClass(mangleClass);
  1.1270 -                    emit(smapper, out, "@4(false)._@3.call(@2, @1);",
  1.1271 +                    emit(smapper, this, "@4(false)._@3.call(@2, @1);",
  1.1272                           smapper.popT(type),
  1.1273                           smapper.popA(), fi[1], 
  1.1274                           mangleClassAccess
  1.1275 @@ -1254,7 +1276,7 @@
  1.1276                      String[] fi = jc.getFieldInfoName(indx);
  1.1277                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  1.1278                      String ac = accessClass(mangleClassName(fi[0]));
  1.1279 -                    smapper.assign(out, type, ac + "(false)._" + fi[1] + "()");
  1.1280 +                    smapper.assign(this, type, ac + "(false)._" + fi[1] + "()");
  1.1281                      i += 2;
  1.1282                      addReference(fi[0]);
  1.1283                      break;
  1.1284 @@ -1263,7 +1285,7 @@
  1.1285                      int indx = readUShortArg(byteCodes, i);
  1.1286                      String[] fi = jc.getFieldInfoName(indx);
  1.1287                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  1.1288 -                    emit(smapper, out, "@1(false)._@2(@3);",
  1.1289 +                    emit(smapper, this, "@1(false)._@2(@3);",
  1.1290                           accessClass(mangleClassName(fi[0])), fi[1],
  1.1291                           smapper.popT(type));
  1.1292                      i += 2;
  1.1293 @@ -1286,7 +1308,7 @@
  1.1294                      final CharSequence v = smapper.popA();
  1.1295                      smapper.clear();
  1.1296  
  1.1297 -                    emit(smapper, out, "{ var @1 = @2; throw @2; }",
  1.1298 +                    emit(smapper, this, "{ var @1 = @2; throw @2; }",
  1.1299                           smapper.pushA(), v);
  1.1300                      break;
  1.1301                  }
  1.1302 @@ -1309,37 +1331,37 @@
  1.1303  
  1.1304                  default: {
  1.1305                      wide = false;
  1.1306 -                    emit(smapper, out, "throw 'unknown bytecode @1';",
  1.1307 +                    emit(smapper, this, "throw 'unknown bytecode @1';",
  1.1308                           Integer.toString(c));
  1.1309                  }
  1.1310              }
  1.1311              if (debug(" //")) {
  1.1312                  generateByteCodeComment(prev, i, byteCodes);
  1.1313              }
  1.1314 -            out.append("\n");            
  1.1315 +            append("\n");            
  1.1316          }
  1.1317          if (previousTrap != null) {
  1.1318              generateCatch(previousTrap, byteCodes.length, topMostLabel);
  1.1319          }
  1.1320          if (didBranches) {
  1.1321 -            out.append("\n    }\n");
  1.1322 +            append("\n    }\n");
  1.1323          }
  1.1324          while (openBraces-- > 0) {
  1.1325 -            out.append('}');
  1.1326 +            append('}');
  1.1327          }
  1.1328 -        out.append("\n};");
  1.1329 +        append("\n};");
  1.1330      }
  1.1331  
  1.1332      private int generateIf(StackMapper mapper, byte[] byteCodes, 
  1.1333          int i, final CharSequence v2, final CharSequence v1, 
  1.1334          final String test, int topMostLabel
  1.1335      ) throws IOException {
  1.1336 -        mapper.flush(out);
  1.1337 +        mapper.flush(this);
  1.1338          int indx = i + readShortArg(byteCodes, i);
  1.1339 -        out.append("if ((").append(v1)
  1.1340 +        append("if ((").append(v1)
  1.1341             .append(") ").append(test).append(" (")
  1.1342             .append(v2).append(")) ");
  1.1343 -        goTo(out, i, indx, topMostLabel);
  1.1344 +        goTo(this, i, indx, topMostLabel);
  1.1345          return i + 2;
  1.1346      }
  1.1347      
  1.1348 @@ -1526,31 +1548,31 @@
  1.1349          }
  1.1350  
  1.1351          if (returnType[0] != 'V') {
  1.1352 -            out.append("var ")
  1.1353 +            append("var ")
  1.1354                 .append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  1.1355                 .append(" = ");
  1.1356          }
  1.1357  
  1.1358          final String in = mi[0];
  1.1359 -        out.append(accessClass(mangleClassName(in)));
  1.1360 -        out.append("(false).");
  1.1361 +        append(accessClass(mangleClassName(in)));
  1.1362 +        append("(false).");
  1.1363          if (mn.startsWith("cons_")) {
  1.1364 -            out.append("constructor.");
  1.1365 +            append("constructor.");
  1.1366          }
  1.1367 -        out.append(mn);
  1.1368 +        append(mn);
  1.1369          if (isStatic) {
  1.1370 -            out.append('(');
  1.1371 +            append('(');
  1.1372          } else {
  1.1373 -            out.append(".call(");
  1.1374 +            append(".call(");
  1.1375          }
  1.1376          if (numArguments > 0) {
  1.1377 -            out.append(vars[0]);
  1.1378 +            append(vars[0]);
  1.1379              for (int j = 1; j < numArguments; ++j) {
  1.1380 -                out.append(", ");
  1.1381 -                out.append(vars[j]);
  1.1382 +                append(", ");
  1.1383 +                append(vars[j]);
  1.1384              }
  1.1385          }
  1.1386 -        out.append(");");
  1.1387 +        append(");");
  1.1388          i += 2;
  1.1389          addReference(in);
  1.1390          return i;
  1.1391 @@ -1571,21 +1593,21 @@
  1.1392          }
  1.1393  
  1.1394          if (returnType[0] != 'V') {
  1.1395 -            out.append("var ")
  1.1396 +            append("var ")
  1.1397                 .append(mapper.pushT(VarType.fromFieldType(returnType[0])))
  1.1398                 .append(" = ");
  1.1399          }
  1.1400  
  1.1401 -        out.append(vars[0]).append('.');
  1.1402 -        out.append(mn);
  1.1403 -        out.append('(');
  1.1404 +        append(vars[0]).append('.');
  1.1405 +        append(mn);
  1.1406 +        append('(');
  1.1407          String sep = "";
  1.1408          for (int j = 1; j < numArguments; ++j) {
  1.1409 -            out.append(sep);
  1.1410 -            out.append(vars[j]);
  1.1411 +            append(sep);
  1.1412 +            append(vars[j]);
  1.1413              sep = ", ";
  1.1414          }
  1.1415 -        out.append(");");
  1.1416 +        append(");");
  1.1417          i += 2;
  1.1418          return i;
  1.1419      }
  1.1420 @@ -1674,31 +1696,31 @@
  1.1421          }
  1.1422          StringBuilder cnt = new StringBuilder();
  1.1423          final String mn = findMethodName(m, cnt);
  1.1424 -        out.append(destObject).append(".").append(mn);
  1.1425 -        out.append(" = function(");
  1.1426 +        append(destObject).append(".").append(mn);
  1.1427 +        append(" = function(");
  1.1428          String space = "";
  1.1429          int index = 0;
  1.1430          StringBuilder toValue = new StringBuilder();
  1.1431          for (int i = 0; i < cnt.length(); i++) {
  1.1432 -            out.append(space);
  1.1433 -            space = outputArg(out, p.args, index);
  1.1434 +            append(space);
  1.1435 +            space = outputArg(this, p.args, index);
  1.1436              if (p.html4j && space.length() > 0) {
  1.1437                  toValue.append("\n  ").append(p.args[index]).append(" = vm.org_apidesign_bck2brwsr_emul_lang_System(false).toJS(").
  1.1438                      append(p.args[index]).append(");");
  1.1439              }
  1.1440              index++;
  1.1441          }
  1.1442 -        out.append(") {").append("\n");
  1.1443 -        out.append(toValue.toString());
  1.1444 +        append(") {").append("\n");
  1.1445 +        append(toValue.toString());
  1.1446          if (p.javacall) {
  1.1447              int lastSlash = jc.getClassName().lastIndexOf('/');
  1.1448              final String pkg = jc.getClassName().substring(0, lastSlash);
  1.1449 -            out.append(mangleCallbacks(pkg, p.body));
  1.1450 +            append(mangleCallbacks(pkg, p.body));
  1.1451              requireReference(pkg + "/$JsCallbacks$");
  1.1452          } else {
  1.1453 -            out.append(p.body);
  1.1454 +            append(p.body);
  1.1455          }
  1.1456 -        out.append("\n}\n");
  1.1457 +        append("\n}\n");
  1.1458          return mn;
  1.1459      }
  1.1460      
  1.1461 @@ -1870,7 +1892,7 @@
  1.1462          return " = null;";
  1.1463      }
  1.1464  
  1.1465 -    private void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
  1.1466 +    private void generateAnno(ClassData cd, byte[] data) throws IOException {
  1.1467          AnnotationParser ap = new AnnotationParser(true, false) {
  1.1468              int[] cnt = new int[32];
  1.1469              int depth;
  1.1470 @@ -1881,39 +1903,39 @@
  1.1471                  requireReference(slashType);
  1.1472                  
  1.1473                  if (cnt[depth]++ > 0) {
  1.1474 -                    out.append(",");
  1.1475 +                    append(",");
  1.1476                  }
  1.1477                  if (top) {
  1.1478 -                    out.append('"').append(attrType).append("\" : ");
  1.1479 +                    append('"').append(attrType).append("\" : ");
  1.1480                  }
  1.1481 -                out.append("{\n");
  1.1482 +                append("{\n");
  1.1483                  cnt[++depth] = 0;
  1.1484              }
  1.1485  
  1.1486              @Override
  1.1487              protected void visitAnnotationEnd(String type, boolean top) throws IOException {
  1.1488 -                out.append("\n}\n");
  1.1489 +                append("\n}\n");
  1.1490                  depth--;
  1.1491              }
  1.1492  
  1.1493              @Override
  1.1494              protected void visitValueStart(String attrName, char type) throws IOException {
  1.1495                  if (cnt[depth]++ > 0) {
  1.1496 -                    out.append(",\n");
  1.1497 +                    append(",\n");
  1.1498                  }
  1.1499                  cnt[++depth] = 0;
  1.1500                  if (attrName != null) {
  1.1501 -                    out.append(attrName).append(" : ");
  1.1502 +                    append(attrName).append(" : ");
  1.1503                  }
  1.1504                  if (type == '[') {
  1.1505 -                    out.append("[");
  1.1506 +                    append("[");
  1.1507                  }
  1.1508              }
  1.1509  
  1.1510              @Override
  1.1511              protected void visitValueEnd(String attrName, char type) throws IOException {
  1.1512                  if (type == '[') {
  1.1513 -                    out.append("]");
  1.1514 +                    append("]");
  1.1515                  }
  1.1516                  depth--;
  1.1517              }
  1.1518 @@ -1924,7 +1946,7 @@
  1.1519                  if (attr == null && value == null) {
  1.1520                      return;
  1.1521                  }
  1.1522 -                out.append(value);
  1.1523 +                append(value);
  1.1524              }
  1.1525  
  1.1526              @Override
  1.1527 @@ -1933,7 +1955,7 @@
  1.1528                  final String slashType = attrType.substring(1, attrType.length() - 1);
  1.1529                  requireReference(slashType);
  1.1530                  
  1.1531 -                out.append(accessClass(mangleClassName(slashType)))
  1.1532 +                append(accessClass(mangleClassName(slashType)))
  1.1533                     .append("(false).constructor.fld_").append(value);
  1.1534              }
  1.1535          };
  1.1536 @@ -1954,12 +1976,11 @@
  1.1537  
  1.1538      final void emitNoFlush(
  1.1539          StackMapper sm, 
  1.1540 -        final Appendable out, 
  1.1541          final String format, final CharSequence... params
  1.1542      ) throws IOException {
  1.1543 -        emitImpl(out, format, params);
  1.1544 +        emitImpl(this, format, params);
  1.1545      }
  1.1546 -    final void emit(
  1.1547 +    static final void emit(
  1.1548          StackMapper sm, 
  1.1549          final Appendable out, 
  1.1550          final String format, final CharSequence... params
  1.1551 @@ -1993,7 +2014,7 @@
  1.1552      }
  1.1553  
  1.1554      private void generateCatch(TrapData[] traps, int current, int topMostLabel) throws IOException {
  1.1555 -        out.append("} catch (e) {\n");
  1.1556 +        append("} catch (e) {\n");
  1.1557          int finallyPC = -1;
  1.1558          for (TrapData e : traps) {
  1.1559              if (e == null) {
  1.1560 @@ -2002,22 +2023,22 @@
  1.1561              if (e.catch_cpx != 0) { //not finally
  1.1562                  final String classInternalName = jc.getClassName(e.catch_cpx);
  1.1563                  addReference(classInternalName);
  1.1564 -                out.append("e = vm.java_lang_Throwable(false).bck2BrwsrCnvrt(e);");
  1.1565 -                out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  1.1566 -                out.append("var stA0 = e;");
  1.1567 -                goTo(out, current, e.handler_pc, topMostLabel);
  1.1568 -                out.append("}\n");
  1.1569 +                append("e = vm.java_lang_Throwable(false).bck2BrwsrCnvrt(e);");
  1.1570 +                append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  1.1571 +                append("var stA0 = e;");
  1.1572 +                goTo(this, current, e.handler_pc, topMostLabel);
  1.1573 +                append("}\n");
  1.1574              } else {
  1.1575                  finallyPC = e.handler_pc;
  1.1576              }
  1.1577          }
  1.1578          if (finallyPC == -1) {
  1.1579 -            out.append("throw e;");
  1.1580 +            append("throw e;");
  1.1581          } else {
  1.1582 -            out.append("var stA0 = e;");
  1.1583 -            goTo(out, current, finallyPC, topMostLabel);
  1.1584 +            append("var stA0 = e;");
  1.1585 +            goTo(this, current, finallyPC, topMostLabel);
  1.1586          }
  1.1587 -        out.append("\n}");
  1.1588 +        append("\n}");
  1.1589      }
  1.1590  
  1.1591      private static void goTo(Appendable out, int current, int to, int canBack) throws IOException {
  1.1592 @@ -2056,7 +2077,7 @@
  1.1593              case 11: jvmType = "[J"; break;
  1.1594              default: throw new IllegalStateException("Array type: " + atype);
  1.1595          }
  1.1596 -        emit(smapper, out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
  1.1597 +        emit(smapper, this, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
  1.1598               smapper.popI(), smapper.pushA(), jvmType);
  1.1599      }
  1.1600  
  1.1601 @@ -2067,7 +2088,7 @@
  1.1602          } else {
  1.1603              typeName = "[L" + typeName + ";";
  1.1604          }
  1.1605 -        emit(smapper, out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
  1.1606 +        emit(smapper, this, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
  1.1607               smapper.popI(), smapper.pushA(), typeName);
  1.1608      }
  1.1609  
  1.1610 @@ -2083,7 +2104,7 @@
  1.1611              dims.insert(1, smapper.popI());
  1.1612          }
  1.1613          dims.append(']');
  1.1614 -        emit(smapper, out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
  1.1615 +        emit(smapper, this, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
  1.1616               dims.toString(), smapper.pushA(), typeName);
  1.1617          return i;
  1.1618      }
  1.1619 @@ -2097,17 +2118,17 @@
  1.1620          int high = readInt4(byteCodes, table);
  1.1621          table += 4;
  1.1622          final CharSequence swVar = smapper.popValue();
  1.1623 -        smapper.flush(out);
  1.1624 -        out.append("switch (").append(swVar).append(") {\n");
  1.1625 +        smapper.flush(this);
  1.1626 +        append("switch (").append(swVar).append(") {\n");
  1.1627          while (low <= high) {
  1.1628              int offset = i + readInt4(byteCodes, table);
  1.1629              table += 4;
  1.1630 -            out.append("  case " + low).append(":"); goTo(out, i, offset, topMostLabel); out.append('\n');
  1.1631 +            append("  case " + low).append(":"); goTo(this, i, offset, topMostLabel); append('\n');
  1.1632              low++;
  1.1633          }
  1.1634 -        out.append("  default: ");
  1.1635 -        goTo(out, i, dflt, topMostLabel);
  1.1636 -        out.append("\n}");
  1.1637 +        append("  default: ");
  1.1638 +        goTo(this, i, dflt, topMostLabel);
  1.1639 +        append("\n}");
  1.1640          i = table - 1;
  1.1641          return i;
  1.1642      }
  1.1643 @@ -2119,18 +2140,18 @@
  1.1644          int n = readInt4(byteCodes, table);
  1.1645          table += 4;
  1.1646          final CharSequence swVar = smapper.popValue();
  1.1647 -        smapper.flush(out);
  1.1648 -        out.append("switch (").append(swVar).append(") {\n");
  1.1649 +        smapper.flush(this);
  1.1650 +        append("switch (").append(swVar).append(") {\n");
  1.1651          while (n-- > 0) {
  1.1652              int cnstnt = readInt4(byteCodes, table);
  1.1653              table += 4;
  1.1654              int offset = i + readInt4(byteCodes, table);
  1.1655              table += 4;
  1.1656 -            out.append("  case " + cnstnt).append(": "); goTo(out, i, offset, topMostLabel); out.append('\n');
  1.1657 +            append("  case " + cnstnt).append(": "); goTo(this, i, offset, topMostLabel); append('\n');
  1.1658          }
  1.1659 -        out.append("  default: ");
  1.1660 -        goTo(out, i, dflt, topMostLabel);
  1.1661 -        out.append("\n}");
  1.1662 +        append("  default: ");
  1.1663 +        goTo(this, i, dflt, topMostLabel);
  1.1664 +        append("\n}");
  1.1665          i = table - 1;
  1.1666          return i;
  1.1667      }
  1.1668 @@ -2138,11 +2159,11 @@
  1.1669      private void generateInstanceOf(int indx, final StackMapper smapper) throws IOException {
  1.1670          final String type = jc.getClassName(indx);
  1.1671          if (!type.startsWith("[")) {
  1.1672 -            emit(smapper, out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
  1.1673 +            emit(smapper, this, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
  1.1674                   smapper.popA(), smapper.pushI(),
  1.1675                   type.replace('/', '_'));
  1.1676          } else {
  1.1677 -            emit(smapper, out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
  1.1678 +            emit(smapper, this, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
  1.1679                  smapper.popA(), smapper.pushI(),
  1.1680                  type
  1.1681              );
  1.1682 @@ -2152,11 +2173,11 @@
  1.1683      private void generateCheckcast(int indx, final StackMapper smapper) throws IOException {
  1.1684          final String type = jc.getClassName(indx);
  1.1685          if (!type.startsWith("[")) {
  1.1686 -            emitNoFlush(smapper, out,
  1.1687 +            emitNoFlush(smapper, 
  1.1688                   "if (@1 !== null && !@1.$instOf_@2) throw vm.java_lang_ClassCastException(true);",
  1.1689                   smapper.getT(0, VarType.REFERENCE, false), type.replace('/', '_'));
  1.1690          } else {
  1.1691 -            emitNoFlush(smapper, 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.1692 +            emitNoFlush(smapper, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
  1.1693                   smapper.getT(0, VarType.REFERENCE, false), type
  1.1694              );
  1.1695          }
  1.1696 @@ -2164,9 +2185,9 @@
  1.1697  
  1.1698      private void generateByteCodeComment(int prev, int i, final byte[] byteCodes) throws IOException {
  1.1699          for (int j = prev; j <= i; j++) {
  1.1700 -            out.append(" ");
  1.1701 +            append(" ");
  1.1702              final int cc = readUByte(byteCodes, j);
  1.1703 -            out.append(Integer.toString(cc));
  1.1704 +            append(Integer.toString(cc));
  1.1705          }
  1.1706      }
  1.1707  }
     2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed Apr 23 17:48:43 2014 +0200
     2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue Apr 29 16:22:23 2014 +0200
     2.3 @@ -58,7 +58,7 @@
     2.4      }
     2.5  
     2.6      protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
     2.7 -        out.append("(function VM(global) {var fillInVMSkeleton = function(vm) {");
     2.8 +        append("(function VM(global) {var fillInVMSkeleton = function(vm) {");
     2.9          StringArray processed = new StringArray();
    2.10          StringArray initCode = new StringArray();
    2.11          StringArray skipClass = new StringArray();
    2.12 @@ -80,7 +80,7 @@
    2.13                  }
    2.14                  InputStream is = loadClass(l, name);
    2.15                  if (is == null) {
    2.16 -                    lazyReference(out, name);
    2.17 +                    lazyReference(this, name);
    2.18                      skipClass.add(name);
    2.19                      continue;
    2.20                  }
    2.21 @@ -89,22 +89,7 @@
    2.22                      processed.add(name);
    2.23                      initCode.add(ic == null ? "" : ic);
    2.24                  } catch (RuntimeException ex) {
    2.25 -                    if (out instanceof CharSequence) {
    2.26 -                        CharSequence seq = (CharSequence)out;
    2.27 -                        int lastBlock = seq.length();
    2.28 -                        while (lastBlock-- > 0) {
    2.29 -                            if (seq.charAt(lastBlock) == '{') {
    2.30 -                                break;
    2.31 -                            }
    2.32 -                        }
    2.33 -                        throw new IOException("Error while compiling " + name + "\n" 
    2.34 -                            + seq.subSequence(lastBlock + 1, seq.length()), ex
    2.35 -                        );
    2.36 -                    } else {
    2.37 -                        throw new IOException("Error while compiling " + name + "\n" 
    2.38 -                            + out, ex
    2.39 -                        );
    2.40 -                    }
    2.41 +                    throw new IOException("Error while compiling " + name + "\n", ex);
    2.42                  }
    2.43              }
    2.44  
    2.45 @@ -116,7 +101,7 @@
    2.46                  if (emul == null) {
    2.47                      throw new IOException("Can't find " + resource);
    2.48                  }
    2.49 -                readResource(emul, out);
    2.50 +                readResource(emul, this);
    2.51              }
    2.52              scripts = new StringArray();
    2.53              
    2.54 @@ -128,13 +113,13 @@
    2.55                  if (indx >= 0) {
    2.56                      final String theCode = initCode.toArray()[indx];
    2.57                      if (!theCode.isEmpty()) {
    2.58 -                        out.append(theCode).append("\n");
    2.59 +                        append(theCode).append("\n");
    2.60                      }
    2.61                      initCode.toArray()[indx] = "";
    2.62                  }
    2.63              }
    2.64          }
    2.65 -        out.append(
    2.66 +        append(
    2.67                "  return vm;\n"
    2.68              + "  };\n"
    2.69              + "  function mangleClass(name) {\n"
    2.70 @@ -172,7 +157,7 @@
    2.71              + "      loadBytes___3BLjava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2I(loader, null, args, 0);\n"
    2.72              + "    return loader;\n"
    2.73              + "  };\n");
    2.74 -        out.append("}(this));");
    2.75 +        append("}(this));");
    2.76      }
    2.77      private static void readResource(InputStream emul, Appendable out) throws IOException {
    2.78          try {