vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
branchregisters
changeset 283 51043a802035
parent 282 a98d6c5a545e
child 307 eaf4e8387065
     1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Dec 07 15:57:14 2012 +0100
     1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Dec 07 19:16:21 2012 +0100
     1.3 @@ -292,488 +292,421 @@
     1.4              final int c = readByte(byteCodes, i);
     1.5              switch (c) {
     1.6                  case opc_aload_0:
     1.7 -                    out.append(mapper.pushA()).append(" = arg0;");
     1.8 +                    emit(out, "@1 = arg0;", mapper.pushA());
     1.9                      break;
    1.10                  case opc_iload_0:
    1.11 -                    out.append(mapper.pushI()).append(" = arg0;");
    1.12 +                    emit(out, "@1 = arg0;", mapper.pushI());
    1.13                      break;
    1.14                  case opc_lload_0:
    1.15 -                    out.append(mapper.pushL()).append(" = arg0;");
    1.16 +                    emit(out, "@1 = arg0;", mapper.pushL());
    1.17                      break;
    1.18                  case opc_fload_0:
    1.19 -                    out.append(mapper.pushF()).append(" = arg0;");
    1.20 +                    emit(out, "@1 = arg0;", mapper.pushF());
    1.21                      break;
    1.22                  case opc_dload_0:
    1.23 -                    out.append(mapper.pushD()).append(" = arg0;");
    1.24 +                    emit(out, "@1 = arg0;", mapper.pushD());
    1.25                      break;
    1.26                  case opc_aload_1:
    1.27 -                    out.append(mapper.pushA()).append(" = arg1;");
    1.28 +                    emit(out, "@1 = arg1;", mapper.pushA());
    1.29                      break;
    1.30                  case opc_iload_1:
    1.31 -                    out.append(mapper.pushI()).append(" = arg1;");
    1.32 +                    emit(out, "@1 = arg1;", mapper.pushI());
    1.33                      break;
    1.34                  case opc_lload_1:
    1.35 -                    out.append(mapper.pushL()).append(" = arg1;");
    1.36 +                    emit(out, "@1 = arg1;", mapper.pushL());
    1.37                      break;
    1.38                  case opc_fload_1:
    1.39 -                    out.append(mapper.pushF()).append(" = arg1;");
    1.40 +                    emit(out, "@1 = arg1;", mapper.pushF());
    1.41                      break;
    1.42                  case opc_dload_1:
    1.43 -                    out.append(mapper.pushD()).append(" = arg1;");
    1.44 +                    emit(out, "@1 = arg1;", mapper.pushD());
    1.45                      break;
    1.46                  case opc_aload_2:
    1.47 -                    out.append(mapper.pushA()).append(" = arg2;");
    1.48 +                    emit(out, "@1 = arg2;", mapper.pushA());
    1.49                      break;
    1.50                  case opc_iload_2:
    1.51 -                    out.append(mapper.pushI()).append(" = arg2;");
    1.52 +                    emit(out, "@1 = arg2;", mapper.pushI());
    1.53                      break;
    1.54                  case opc_lload_2:
    1.55 -                    out.append(mapper.pushL()).append(" = arg2;");
    1.56 +                    emit(out, "@1 = arg2;", mapper.pushL());
    1.57                      break;
    1.58                  case opc_fload_2:
    1.59 -                    out.append(mapper.pushF()).append(" = arg2;");
    1.60 +                    emit(out, "@1 = arg2;", mapper.pushF());
    1.61                      break;
    1.62                  case opc_dload_2:
    1.63 -                    out.append(mapper.pushD()).append(" = arg2;");
    1.64 +                    emit(out, "@1 = arg2;", mapper.pushD());
    1.65                      break;
    1.66                  case opc_aload_3:
    1.67 -                    out.append(mapper.pushA()).append(" = arg3;");
    1.68 +                    emit(out, "@1 = arg3;", mapper.pushA());
    1.69                      break;
    1.70                  case opc_iload_3:
    1.71 -                    out.append(mapper.pushI()).append(" = arg3;");
    1.72 +                    emit(out, "@1 = arg3;", mapper.pushI());
    1.73                      break;
    1.74                  case opc_lload_3:
    1.75 -                    out.append(mapper.pushL()).append(" = arg3;");
    1.76 +                    emit(out, "@1 = arg3;", mapper.pushL());
    1.77                      break;
    1.78                  case opc_fload_3:
    1.79 -                    out.append(mapper.pushF()).append(" = arg3;");
    1.80 +                    emit(out, "@1 = arg3;", mapper.pushF());
    1.81                      break;
    1.82                  case opc_dload_3:
    1.83 -                    out.append(mapper.pushD()).append(" = arg3;");
    1.84 +                    emit(out, "@1 = arg3;", mapper.pushD());
    1.85                      break;
    1.86                  case opc_iload: {
    1.87                      final int indx = readByte(byteCodes, ++i);
    1.88 -                    out.append(mapper.pushI()).append(" = ")
    1.89 -                       .append("arg").append(indx + ";");
    1.90 +                    emit(out, "@1 = arg@2;",
    1.91 +                         mapper.pushI(), Integer.toString(indx));
    1.92                      break;
    1.93                  }
    1.94                  case opc_lload: {
    1.95                      final int indx = readByte(byteCodes, ++i);
    1.96 -                    out.append(mapper.pushL()).append(" = ")
    1.97 -                       .append("arg").append(indx + ";");
    1.98 +                    emit(out, "@1 = arg@2;",
    1.99 +                         mapper.pushL(), Integer.toString(indx));
   1.100                      break;
   1.101                  }
   1.102                  case opc_fload: {
   1.103                      final int indx = readByte(byteCodes, ++i);
   1.104 -                    out.append(mapper.pushF()).append(" = ")
   1.105 -                       .append("arg").append(indx + ";");
   1.106 +                    emit(out, "@1 = arg@2;",
   1.107 +                         mapper.pushF(), Integer.toString(indx));
   1.108                      break;
   1.109                  }
   1.110                  case opc_dload: {
   1.111                      final int indx = readByte(byteCodes, ++i);
   1.112 -                    out.append(mapper.pushD()).append(" = ")
   1.113 -                       .append("arg").append(indx + ";");
   1.114 +                    emit(out, "@1 = arg@2;",
   1.115 +                         mapper.pushD(), Integer.toString(indx));
   1.116                      break;
   1.117                  }
   1.118                  case opc_aload: {
   1.119                      final int indx = readByte(byteCodes, ++i);
   1.120 -                    out.append(mapper.pushA()).append(" = ")
   1.121 -                       .append("arg").append(indx + ";");
   1.122 +                    emit(out, "@1 = arg@2;",
   1.123 +                         mapper.pushA(), Integer.toString(indx));
   1.124                      break;
   1.125                  }
   1.126                  case opc_istore: {
   1.127                      final int indx = readByte(byteCodes, ++i);
   1.128 -                    out.append("arg" + indx).append(" = ")
   1.129 -                       .append(mapper.popI()).append(';');
   1.130 +                    emit(out, "arg@1 = @2;",
   1.131 +                         Integer.toString(indx), mapper.popI());
   1.132                      break;
   1.133                  }
   1.134                  case opc_lstore: {
   1.135                      final int indx = readByte(byteCodes, ++i);
   1.136 -                    out.append("arg" + indx).append(" = ")
   1.137 -                       .append(mapper.popL()).append(';');
   1.138 +                    emit(out, "arg@1 = @2;",
   1.139 +                         Integer.toString(indx), mapper.popL());
   1.140                      break;
   1.141                  }
   1.142                  case opc_fstore: {
   1.143                      final int indx = readByte(byteCodes, ++i);
   1.144 -                    out.append("arg" + indx).append(" = ")
   1.145 -                       .append(mapper.popF()).append(';');
   1.146 +                    emit(out, "arg@1 = @2;",
   1.147 +                         Integer.toString(indx), mapper.popF());
   1.148                      break;
   1.149                  }
   1.150                  case opc_dstore: {
   1.151                      final int indx = readByte(byteCodes, ++i);
   1.152 -                    out.append("arg" + indx).append(" = ")
   1.153 -                       .append(mapper.popD()).append(';');
   1.154 +                    emit(out, "arg@1 = @2;",
   1.155 +                         Integer.toString(indx), mapper.popD());
   1.156                      break;
   1.157                  }
   1.158                  case opc_astore: {
   1.159                      final int indx = readByte(byteCodes, ++i);
   1.160 -                    out.append("arg" + indx).append(" = ")
   1.161 -                       .append(mapper.popA()).append(';');
   1.162 +                    emit(out, "arg@1 = @2;",
   1.163 +                         Integer.toString(indx), mapper.popA());
   1.164                      break;
   1.165                  }
   1.166                  case opc_astore_0:
   1.167 -                    out.append("arg0 = ").append(mapper.popA()).append(';');
   1.168 +                    emit(out, "arg0 = @1;", mapper.popA());
   1.169                      break;
   1.170                  case opc_istore_0:
   1.171 -                    out.append("arg0 = ").append(mapper.popI()).append(';');
   1.172 +                    emit(out, "arg0 = @1;", mapper.popI());
   1.173                      break;
   1.174                  case opc_lstore_0:
   1.175 -                    out.append("arg0 = ").append(mapper.popL()).append(';');
   1.176 +                    emit(out, "arg0 = @1;", mapper.popL());
   1.177                      break;
   1.178                  case opc_fstore_0:
   1.179 -                    out.append("arg0 = ").append(mapper.popF()).append(';');
   1.180 +                    emit(out, "arg0 = @1;", mapper.popF());
   1.181                      break;
   1.182                  case opc_dstore_0:
   1.183 -                    out.append("arg0 = ").append(mapper.popD()).append(';');
   1.184 +                    emit(out, "arg0 = @1;", mapper.popD());
   1.185                      break;
   1.186                  case opc_astore_1:
   1.187 -                    out.append("arg1 = ").append(mapper.popA()).append(';');
   1.188 +                    emit(out, "arg1 = @1;", mapper.popA());
   1.189                      break;
   1.190                  case opc_istore_1:
   1.191 -                    out.append("arg1 = ").append(mapper.popI()).append(';');
   1.192 +                    emit(out, "arg1 = @1;", mapper.popI());
   1.193                      break;
   1.194                  case opc_lstore_1:
   1.195 -                    out.append("arg1 = ").append(mapper.popL()).append(';');
   1.196 +                    emit(out, "arg1 = @1;", mapper.popL());
   1.197                      break;
   1.198                  case opc_fstore_1:
   1.199 -                    out.append("arg1 = ").append(mapper.popF()).append(';');
   1.200 +                    emit(out, "arg1 = @1;", mapper.popF());
   1.201                      break;
   1.202                  case opc_dstore_1:
   1.203 -                    out.append("arg1 = ").append(mapper.popD()).append(';');
   1.204 +                    emit(out, "arg1 = @1;", mapper.popD());
   1.205                      break;
   1.206                  case opc_astore_2:
   1.207 -                    out.append("arg2 = ").append(mapper.popA()).append(';');
   1.208 +                    emit(out, "arg2 = @1;", mapper.popA());
   1.209                      break;
   1.210                  case opc_istore_2:
   1.211 -                    out.append("arg2 = ").append(mapper.popI()).append(';');
   1.212 +                    emit(out, "arg2 = @1;", mapper.popI());
   1.213                      break;
   1.214                  case opc_lstore_2:
   1.215 -                    out.append("arg2 = ").append(mapper.popL()).append(';');
   1.216 +                    emit(out, "arg2 = @1;", mapper.popL());
   1.217                      break;
   1.218                  case opc_fstore_2:
   1.219 -                    out.append("arg2 = ").append(mapper.popF()).append(';');
   1.220 +                    emit(out, "arg2 = @1;", mapper.popF());
   1.221                      break;
   1.222                  case opc_dstore_2:
   1.223 -                    out.append("arg2 = ").append(mapper.popD()).append(';');
   1.224 +                    emit(out, "arg2 = @1;", mapper.popD());
   1.225                      break;
   1.226                  case opc_astore_3:
   1.227 -                    out.append("arg3 = ").append(mapper.popA()).append(';');
   1.228 +                    emit(out, "arg3 = @1;", mapper.popA());
   1.229                      break;
   1.230                  case opc_istore_3:
   1.231 -                    out.append("arg3 = ").append(mapper.popI()).append(';');
   1.232 +                    emit(out, "arg3 = @1;", mapper.popI());
   1.233                      break;
   1.234                  case opc_lstore_3:
   1.235 -                    out.append("arg3 = ").append(mapper.popL()).append(';');
   1.236 +                    emit(out, "arg3 = @1;", mapper.popL());
   1.237                      break;
   1.238                  case opc_fstore_3:
   1.239 -                    out.append("arg3 = ").append(mapper.popF()).append(';');
   1.240 +                    emit(out, "arg3 = @1;", mapper.popF());
   1.241                      break;
   1.242                  case opc_dstore_3:
   1.243 -                    out.append("arg3 = ").append(mapper.popD()).append(';');
   1.244 +                    emit(out, "arg3 = @1;", mapper.popD());
   1.245                      break;
   1.246                  case opc_iadd:
   1.247 -                    out.append(mapper.getI(1)).append(" += ")
   1.248 -                       .append(mapper.popI()).append(';');
   1.249 +                    emit(out, "@1 += @2;", mapper.getI(1), mapper.popI());
   1.250                      break;
   1.251                  case opc_ladd:
   1.252 -                    out.append(mapper.getL(1)).append(" += ")
   1.253 -                       .append(mapper.popL()).append(';');
   1.254 +                    emit(out, "@1 += @2;", mapper.getL(1), mapper.popL());
   1.255                      break;
   1.256                  case opc_fadd:
   1.257 -                    out.append(mapper.getF(1)).append(" += ")
   1.258 -                       .append(mapper.popF()).append(';');
   1.259 +                    emit(out, "@1 += @2;", mapper.getF(1), mapper.popF());
   1.260                      break;
   1.261                  case opc_dadd:
   1.262 -                    out.append(mapper.getD(1)).append(" += ")
   1.263 -                       .append(mapper.popD()).append(';');
   1.264 +                    emit(out, "@1 += @2;", mapper.getD(1), mapper.popD());
   1.265                      break;
   1.266                  case opc_isub:
   1.267 -                    out.append(mapper.getI(1)).append(" -= ")
   1.268 -                       .append(mapper.popI()).append(';');
   1.269 +                    emit(out, "@1 -= @2;", mapper.getI(1), mapper.popI());
   1.270                      break;
   1.271                  case opc_lsub:
   1.272 -                    out.append(mapper.getL(1)).append(" -= ")
   1.273 -                       .append(mapper.popL()).append(';');
   1.274 +                    emit(out, "@1 -= @2;", mapper.getL(1), mapper.popL());
   1.275                      break;
   1.276                  case opc_fsub:
   1.277 -                    out.append(mapper.getF(1)).append(" -= ")
   1.278 -                       .append(mapper.popF()).append(';');
   1.279 +                    emit(out, "@1 -= @2;", mapper.getF(1), mapper.popF());
   1.280                      break;
   1.281                  case opc_dsub:
   1.282 -                    out.append(mapper.getD(1)).append(" -= ")
   1.283 -                       .append(mapper.popD()).append(';');
   1.284 +                    emit(out, "@1 -= @2;", mapper.getD(1), mapper.popD());
   1.285                      break;
   1.286                  case opc_imul:
   1.287 -                    out.append(mapper.getI(1)).append(" *= ")
   1.288 -                       .append(mapper.popI()).append(';');
   1.289 +                    emit(out, "@1 *= @2;", mapper.getI(1), mapper.popI());
   1.290                      break;
   1.291                  case opc_lmul:
   1.292 -                    out.append(mapper.getL(1)).append(" *= ")
   1.293 -                       .append(mapper.popL()).append(';');
   1.294 +                    emit(out, "@1 *= @2;", mapper.getL(1), mapper.popL());
   1.295                      break;
   1.296                  case opc_fmul:
   1.297 -                    out.append(mapper.getF(1)).append(" *= ")
   1.298 -                       .append(mapper.popF()).append(';');
   1.299 +                    emit(out, "@1 *= @2;", mapper.getF(1), mapper.popF());
   1.300                      break;
   1.301                  case opc_dmul:
   1.302 -                    out.append(mapper.getD(1)).append(" *= ")
   1.303 -                       .append(mapper.popD()).append(';');
   1.304 +                    emit(out, "@1 *= @2;", mapper.getD(1), mapper.popD());
   1.305                      break;
   1.306                  case opc_idiv:
   1.307 -                    out.append(mapper.getI(1)).append(" = ")
   1.308 -                       .append("Math.floor(").append(mapper.getI(1))
   1.309 -                       .append(" / ").append(mapper.popI()).append(");");
   1.310 +                    emit(out, "@1 = Math.floor(@1 / @2);",
   1.311 +                         mapper.getI(1), mapper.popI());
   1.312                      break;
   1.313                  case opc_ldiv:
   1.314 -                    out.append(mapper.getL(1)).append(" = ")
   1.315 -                       .append("Math.floor(").append(mapper.getL(1))
   1.316 -                       .append(" / ").append(mapper.popL()).append(");");
   1.317 +                    emit(out, "@1 = Math.floor(@1 / @2);",
   1.318 +                         mapper.getL(1), mapper.popL());
   1.319                      break;
   1.320                  case opc_fdiv:
   1.321 -                    out.append(mapper.getF(1)).append(" /= ")
   1.322 -                       .append(mapper.popF()).append(';');
   1.323 +                    emit(out, "@1 /= @2;", mapper.getF(1), mapper.popF());
   1.324                      break;
   1.325                  case opc_ddiv:
   1.326 -                    out.append(mapper.getD(1)).append(" /= ")
   1.327 -                       .append(mapper.popD()).append(';');
   1.328 +                    emit(out, "@1 /= @2;", mapper.getD(1), mapper.popD());
   1.329                      break;
   1.330                  case opc_irem:
   1.331 -                    out.append(mapper.getI(1)).append(" %= ")
   1.332 -                       .append(mapper.popI()).append(';');
   1.333 +                    emit(out, "@1 %= @2;", mapper.getI(1), mapper.popI());
   1.334                      break;
   1.335                  case opc_lrem:
   1.336 -                    out.append(mapper.getL(1)).append(" %= ")
   1.337 -                       .append(mapper.popL()).append(';');
   1.338 +                    emit(out, "@1 %= @2;", mapper.getL(1), mapper.popL());
   1.339                      break;
   1.340                  case opc_frem:
   1.341 -                    out.append(mapper.getF(1)).append(" %= ")
   1.342 -                       .append(mapper.popF()).append(';');
   1.343 +                    emit(out, "@1 %= @2;", mapper.getF(1), mapper.popF());
   1.344                      break;
   1.345                  case opc_drem:
   1.346 -                    out.append(mapper.getD(1)).append(" %= ")
   1.347 -                       .append(mapper.popD()).append(';');
   1.348 +                    emit(out, "@1 %= @2;", mapper.getD(1), mapper.popD());
   1.349                      break;
   1.350                  case opc_iand:
   1.351 -                    out.append(mapper.getI(1)).append(" &= ")
   1.352 -                       .append(mapper.popI()).append(';');
   1.353 +                    emit(out, "@1 &= @2;", mapper.getI(1), mapper.popI());
   1.354                      break;
   1.355                  case opc_land:
   1.356 -                    out.append(mapper.getL(1)).append(" &= ")
   1.357 -                       .append(mapper.popL()).append(';');
   1.358 +                    emit(out, "@1 &= @2;", mapper.getL(1), mapper.popL());
   1.359                      break;
   1.360                  case opc_ior:
   1.361 -                    out.append(mapper.getI(1)).append(" |= ")
   1.362 -                       .append(mapper.popI()).append(';');
   1.363 +                    emit(out, "@1 |= @2;", mapper.getI(1), mapper.popI());
   1.364                      break;
   1.365                  case opc_lor:
   1.366 -                    out.append(mapper.getL(1)).append(" |= ")
   1.367 -                       .append(mapper.popL()).append(';');
   1.368 +                    emit(out, "@1 |= @2;", mapper.getL(1), mapper.popL());
   1.369                      break;
   1.370                  case opc_ixor:
   1.371 -                    out.append(mapper.getI(1)).append(" ^= ")
   1.372 -                       .append(mapper.popI()).append(';');
   1.373 +                    emit(out, "@1 ^= @2;", mapper.getI(1), mapper.popI());
   1.374                      break;
   1.375                  case opc_lxor:
   1.376 -                    out.append(mapper.getL(1)).append(" ^= ")
   1.377 -                       .append(mapper.popL()).append(';');
   1.378 +                    emit(out, "@1 ^= @2;", mapper.getL(1), mapper.popL());
   1.379                      break;
   1.380                  case opc_ineg:
   1.381 -                    out.append(mapper.getI(0)).append(" = -")
   1.382 -                       .append(mapper.getI(0)).append(';');
   1.383 +                    emit(out, "@1 = -@1;", mapper.getI(0));
   1.384                      break;
   1.385                  case opc_lneg:
   1.386 -                    out.append(mapper.getL(0)).append(" = -")
   1.387 -                       .append(mapper.getL(0)).append(';');
   1.388 +                    emit(out, "@1 = -@1;", mapper.getL(0));
   1.389                      break;
   1.390                  case opc_fneg:
   1.391 -                    out.append(mapper.getF(0)).append(" = -")
   1.392 -                       .append(mapper.getF(0)).append(';');
   1.393 +                    emit(out, "@1 = -@1;", mapper.getF(0));
   1.394                      break;
   1.395                  case opc_dneg:
   1.396 -                    out.append(mapper.getD(0)).append(" = -")
   1.397 -                       .append(mapper.getD(0)).append(';');
   1.398 +                    emit(out, "@1 = -@1;", mapper.getD(0));
   1.399                      break;
   1.400                  case opc_ishl:
   1.401 -                    out.append(mapper.getI(1)).append(" <<= ")
   1.402 -                       .append(mapper.popI()).append(';');
   1.403 +                    emit(out, "@1 <<= @2;", mapper.getI(1), mapper.popI());
   1.404                      break;
   1.405                  case opc_lshl:
   1.406 -                    out.append(mapper.getL(1)).append(" <<= ")
   1.407 -                       .append(mapper.popI()).append(';');
   1.408 +                    emit(out, "@1 <<= @2;", mapper.getL(1), mapper.popI());
   1.409                      break;
   1.410                  case opc_ishr:
   1.411 -                    out.append(mapper.getI(1)).append(" >>= ")
   1.412 -                       .append(mapper.popI()).append(';');
   1.413 +                    emit(out, "@1 >>= @2;", mapper.getI(1), mapper.popI());
   1.414                      break;
   1.415                  case opc_lshr:
   1.416 -                    out.append(mapper.getL(1)).append(" >>= ")
   1.417 -                       .append(mapper.popI()).append(';');
   1.418 +                    emit(out, "@1 >>= @2;", mapper.getL(1), mapper.popI());
   1.419                      break;
   1.420                  case opc_iushr:
   1.421 -                    out.append(mapper.getI(1)).append(" >>>= ")
   1.422 -                       .append(mapper.popI()).append(';');
   1.423 +                    emit(out, "@1 >>>= @2;", mapper.getI(1), mapper.popI());
   1.424                      break;
   1.425                  case opc_lushr:
   1.426 -                    out.append(mapper.getL(1)).append(" >>>= ")
   1.427 -                       .append(mapper.popI()).append(';');
   1.428 +                    emit(out, "@1 >>>= @2;", mapper.getL(1), mapper.popI());
   1.429                      break;
   1.430                  case opc_iinc: {
   1.431                      final int varIndx = readByte(byteCodes, ++i);
   1.432                      final int incrBy = byteCodes[++i];
   1.433                      if (incrBy == 1) {
   1.434 -                        out.append("arg" + varIndx).append("++;");
   1.435 +                        emit(out, "arg@1++;", Integer.toString(varIndx));
   1.436                      } else {
   1.437 -                        out.append("arg" + varIndx).append(" += " + incrBy).append(";");
   1.438 +                        emit(out, "arg@1 += @2;",
   1.439 +                             Integer.toString(varIndx),
   1.440 +                             Integer.toString(incrBy));
   1.441                      }
   1.442                      break;
   1.443                  }
   1.444                  case opc_return:
   1.445 -                    out.append("return;");
   1.446 +                    emit(out, "return;");
   1.447                      break;
   1.448                  case opc_ireturn:
   1.449 -                    out.append("return ").append(mapper.popI()).append(';');
   1.450 +                    emit(out, "return @1;", mapper.popI());
   1.451                      break;
   1.452                  case opc_lreturn:
   1.453 -                    out.append("return ").append(mapper.popL()).append(';');
   1.454 +                    emit(out, "return @1;", mapper.popL());
   1.455                      break;
   1.456                  case opc_freturn:
   1.457 -                    out.append("return ").append(mapper.popF()).append(';');
   1.458 +                    emit(out, "return @1;", mapper.popF());
   1.459                      break;
   1.460                  case opc_dreturn:
   1.461 -                    out.append("return ").append(mapper.popD()).append(';');
   1.462 +                    emit(out, "return @1;", mapper.popD());
   1.463                      break;
   1.464                  case opc_areturn:
   1.465 -                    out.append("return ").append(mapper.popA()).append(';');
   1.466 +                    emit(out, "return @1;", mapper.popA());
   1.467                      break;
   1.468 -                case opc_i2l: {
   1.469 -                    final Variable v = mapper.popI();
   1.470 -                    out.append(mapper.pushL()).append(" = ")
   1.471 -                       .append(v).append(';');
   1.472 +                case opc_i2l:
   1.473 +                    emit(out, "@2 = @1;", mapper.popI(), mapper.pushL());
   1.474                      break;
   1.475 -                }
   1.476 -                case opc_i2f: {
   1.477 -                    final Variable v = mapper.popI();
   1.478 -                    out.append(mapper.pushF()).append(" = ")
   1.479 -                       .append(v).append(';');
   1.480 +                case opc_i2f:
   1.481 +                    emit(out, "@2 = @1;", mapper.popI(), mapper.pushF());
   1.482                      break;
   1.483 -                }
   1.484 -                case opc_i2d: {
   1.485 -                    final Variable v = mapper.popI();
   1.486 -                    out.append(mapper.pushD()).append(" = ")
   1.487 -                       .append(v).append(';');
   1.488 +                case opc_i2d:
   1.489 +                    emit(out, "@2 = @1;", mapper.popI(), mapper.pushD());
   1.490                      break;
   1.491 -                }
   1.492 -                case opc_l2i: {
   1.493 -                    final Variable v = mapper.popL();
   1.494 -                    out.append(mapper.pushI()).append(" = ")
   1.495 -                       .append(v).append(';');
   1.496 +                case opc_l2i:
   1.497 +                    emit(out, "@2 = @1;", mapper.popL(), mapper.pushI());
   1.498                      break;
   1.499 -                }
   1.500                      // max int check?
   1.501 -                case opc_l2f: {
   1.502 -                    final Variable v = mapper.popL();
   1.503 -                    out.append(mapper.pushF()).append(" = ")
   1.504 -                       .append(v).append(';');
   1.505 +                case opc_l2f:
   1.506 +                    emit(out, "@2 = @1;", mapper.popL(), mapper.pushF());
   1.507                      break;
   1.508 -                }
   1.509 -                case opc_l2d: {
   1.510 -                    final Variable v = mapper.popL();
   1.511 -                    out.append(mapper.pushD()).append(" = ")
   1.512 -                       .append(v).append(';');
   1.513 +                case opc_l2d:
   1.514 +                    emit(out, "@2 = @1;", mapper.popL(), mapper.pushD());
   1.515                      break;
   1.516 -                }
   1.517 -                case opc_f2d: {
   1.518 -                    final Variable v = mapper.popF();
   1.519 -                    out.append(mapper.pushD()).append(" = ")
   1.520 -                       .append(v).append(';');
   1.521 +                case opc_f2d:
   1.522 +                    emit(out, "@2 = @1;", mapper.popF(), mapper.pushD());
   1.523                      break;
   1.524 -                }
   1.525 -                case opc_d2f: {
   1.526 -                    final Variable v = mapper.popD();
   1.527 -                    out.append(mapper.pushF()).append(" = ")
   1.528 -                       .append(v).append(';');
   1.529 +                case opc_d2f:
   1.530 +                    emit(out, "@2 = @1;", mapper.popD(), mapper.pushF());
   1.531                      break;
   1.532 -                }
   1.533 -                case opc_f2i: {
   1.534 -                    final Variable v = mapper.popF();
   1.535 -                    out.append(mapper.pushI()).append(" = ")
   1.536 -                       .append("Math.floor(").append(v).append(");");
   1.537 +                case opc_f2i:
   1.538 +                    emit(out, "@2 = Math.floor(@1);",
   1.539 +                         mapper.popF(), mapper.pushI());
   1.540                      break;
   1.541 -                }
   1.542 -                case opc_f2l: {
   1.543 -                    final Variable v = mapper.popF();
   1.544 -                    out.append(mapper.pushL()).append(" = ")
   1.545 -                       .append("Math.floor(").append(v).append(");");
   1.546 +                case opc_f2l:
   1.547 +                    emit(out, "@2 = Math.floor(@1);",
   1.548 +                         mapper.popF(), mapper.pushL());
   1.549                      break;
   1.550 -                }
   1.551 -                case opc_d2i: {
   1.552 -                    final Variable v = mapper.popD();
   1.553 -                    out.append(mapper.pushI()).append(" = ")
   1.554 -                       .append("Math.floor(").append(v).append(");");
   1.555 +                case opc_d2i:
   1.556 +                    emit(out, "@2 = Math.floor(@1);",
   1.557 +                         mapper.popD(), mapper.pushI());
   1.558                      break;
   1.559 -                }
   1.560 -                case opc_d2l: {
   1.561 -                    final Variable v = mapper.popD();
   1.562 -                    out.append(mapper.pushL()).append(" = ")
   1.563 -                       .append("Math.floor(").append(v).append(");");
   1.564 +                case opc_d2l:
   1.565 +                    emit(out, "@2 = Math.floor(@1);",
   1.566 +                         mapper.popD(), mapper.pushL());
   1.567                      break;
   1.568 -                }
   1.569                  case opc_i2b:
   1.570                  case opc_i2c:
   1.571                  case opc_i2s:
   1.572                      out.append("/* number conversion */");
   1.573                      break;
   1.574                  case opc_aconst_null:
   1.575 -                    out.append(mapper.pushA()).append(" = null;");
   1.576 +                    emit(out, "@1 = null;", mapper.pushA());
   1.577                      break;
   1.578                  case opc_iconst_m1:
   1.579 -                    out.append(mapper.pushI()).append(" = -1;");
   1.580 +                    emit(out, "@1 = -1;", mapper.pushI());
   1.581                      break;
   1.582                  case opc_iconst_0:
   1.583 -                    out.append(mapper.pushI()).append(" = 0;");
   1.584 +                    emit(out, "@1 = 0;", mapper.pushI());
   1.585                      break;
   1.586                  case opc_dconst_0:
   1.587 -                    out.append(mapper.pushD()).append(" = 0;");
   1.588 +                    emit(out, "@1 = 0;", mapper.pushD());
   1.589                      break;
   1.590                  case opc_lconst_0:
   1.591 -                    out.append(mapper.pushL()).append(" = 0;");
   1.592 +                    emit(out, "@1 = 0;", mapper.pushL());
   1.593                      break;
   1.594                  case opc_fconst_0:
   1.595 -                    out.append(mapper.pushF()).append(" = 0;");
   1.596 +                    emit(out, "@1 = 0;", mapper.pushF());
   1.597                      break;
   1.598                  case opc_iconst_1:
   1.599 -                    out.append(mapper.pushI()).append(" = 1;");
   1.600 +                    emit(out, "@1 = 1;", mapper.pushI());
   1.601                      break;
   1.602                  case opc_lconst_1:
   1.603 -                    out.append(mapper.pushL()).append(" = 1;");
   1.604 +                    emit(out, "@1 = 1;", mapper.pushL());
   1.605                      break;
   1.606                  case opc_fconst_1:
   1.607 -                    out.append(mapper.pushF()).append(" = 1;");
   1.608 +                    emit(out, "@1 = 1;", mapper.pushF());
   1.609                      break;
   1.610                  case opc_dconst_1:
   1.611 -                    out.append(mapper.pushD()).append(" = 1;");
   1.612 +                    emit(out, "@1 = 1;", mapper.pushD());
   1.613                      break;
   1.614                  case opc_iconst_2:
   1.615 -                    out.append(mapper.pushI()).append(" = 2;");
   1.616 +                    emit(out, "@1 = 2;", mapper.pushI());
   1.617                      break;
   1.618                  case opc_fconst_2:
   1.619 -                    out.append(mapper.pushF()).append(" = 2;");
   1.620 +                    emit(out, "@1 = 2;", mapper.pushF());
   1.621                      break;
   1.622                  case opc_iconst_3:
   1.623 -                    out.append(mapper.pushI()).append(" = 3;");
   1.624 +                    emit(out, "@1 = 3;", mapper.pushI());
   1.625                      break;
   1.626                  case opc_iconst_4:
   1.627 -                    out.append(mapper.pushI()).append(" = 4;");
   1.628 +                    emit(out, "@1 = 4;", mapper.pushI());
   1.629                      break;
   1.630                  case opc_iconst_5:
   1.631 -                    out.append(mapper.pushI()).append(" = 5;");
   1.632 +                    emit(out, "@1 = 5;", mapper.pushI());
   1.633                      break;
   1.634                  case opc_ldc: {
   1.635                      int indx = readByte(byteCodes, ++i);
   1.636                      String v = encodeConstant(indx);
   1.637                      int type = constantToVariableType(jc.getTag(indx));
   1.638 -                    out.append(mapper.pushT(type)).append(" = ")
   1.639 -                       .append(v).append(';');
   1.640 +                    emit(out, "@1 = @2;", mapper.pushT(type), v);
   1.641                      break;
   1.642                  }
   1.643                  case opc_ldc_w:
   1.644 @@ -782,20 +715,22 @@
   1.645                      i += 2;
   1.646                      String v = encodeConstant(indx);
   1.647                      int type = constantToVariableType(jc.getTag(indx));
   1.648 -                    out.append(mapper.pushT(type)).append(" = ")
   1.649 -                       .append(v).append(';');
   1.650 +                    emit(out, "@1 = @2;", mapper.pushT(type), v);
   1.651                      break;
   1.652                  }
   1.653                  case opc_lcmp:
   1.654 -                    generateCmp(mapper.popL(), mapper.popL(), mapper.pushI());
   1.655 +                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
   1.656 +                         mapper.popL(), mapper.popL(), mapper.pushI());
   1.657                      break;
   1.658                  case opc_fcmpl:
   1.659                  case opc_fcmpg:
   1.660 -                    generateCmp(mapper.popF(), mapper.popF(), mapper.pushI());
   1.661 +                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
   1.662 +                         mapper.popF(), mapper.popF(), mapper.pushI());
   1.663                      break;
   1.664                  case opc_dcmpl:
   1.665                  case opc_dcmpg:
   1.666 -                    generateCmp(mapper.popD(), mapper.popD(), mapper.pushI());
   1.667 +                    emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
   1.668 +                         mapper.popD(), mapper.popD(), mapper.pushI());
   1.669                      break;
   1.670                  case opc_if_acmpeq:
   1.671                      i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
   1.672 @@ -805,72 +740,63 @@
   1.673                      i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
   1.674                                     "!=");
   1.675                      break;
   1.676 -                case opc_if_icmpeq: {
   1.677 +                case opc_if_icmpeq:
   1.678                      i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
   1.679                                     "==");
   1.680                      break;
   1.681 -                }
   1.682                  case opc_ifeq: {
   1.683                      int indx = i + readIntArg(byteCodes, i);
   1.684 -                    out.append("if (").append(mapper.popI())
   1.685 -                                      .append(" == 0) { gt = " + indx);
   1.686 -                    out.append("; continue; }");
   1.687 +                    emit(out, "if (@1 == 0) { gt = @2; continue; }",
   1.688 +                         mapper.popI(), Integer.toString(indx));
   1.689                      i += 2;
   1.690                      break;
   1.691                  }
   1.692                  case opc_ifne: {
   1.693                      int indx = i + readIntArg(byteCodes, i);
   1.694 -                    out.append("if (").append(mapper.popI())
   1.695 -                                      .append(" != 0) { gt = " + indx);
   1.696 -                    out.append("; continue; }");
   1.697 +                    emit(out, "if (@1 != 0) { gt = @2; continue; }",
   1.698 +                         mapper.popI(), Integer.toString(indx));
   1.699                      i += 2;
   1.700                      break;
   1.701                  }
   1.702                  case opc_iflt: {
   1.703                      int indx = i + readIntArg(byteCodes, i);
   1.704 -                    out.append("if (").append(mapper.popI())
   1.705 -                                      .append(" < 0) { gt = " + indx);
   1.706 -                    out.append("; continue; }");
   1.707 +                    emit(out, "if (@1 < 0) { gt = @2; continue; }",
   1.708 +                         mapper.popI(), Integer.toString(indx));
   1.709                      i += 2;
   1.710                      break;
   1.711                  }
   1.712                  case opc_ifle: {
   1.713                      int indx = i + readIntArg(byteCodes, i);
   1.714 -                    out.append("if (").append(mapper.popI())
   1.715 -                                      .append(" <= 0) { gt = " + indx);
   1.716 -                    out.append("; continue; }");
   1.717 +                    emit(out, "if (@1 <= 0) { gt = @2; continue; }",
   1.718 +                         mapper.popI(), Integer.toString(indx));
   1.719                      i += 2;
   1.720                      break;
   1.721                  }
   1.722                  case opc_ifgt: {
   1.723                      int indx = i + readIntArg(byteCodes, i);
   1.724 -                    out.append("if (").append(mapper.popI())
   1.725 -                                      .append(" > 0) { gt = " + indx);
   1.726 -                    out.append("; continue; }");
   1.727 +                    emit(out, "if (@1 > 0) { gt = @2; continue; }",
   1.728 +                         mapper.popI(), Integer.toString(indx));
   1.729                      i += 2;
   1.730                      break;
   1.731                  }
   1.732                  case opc_ifge: {
   1.733                      int indx = i + readIntArg(byteCodes, i);
   1.734 -                    out.append("if (").append(mapper.popI())
   1.735 -                                      .append(" >= 0) { gt = " + indx);
   1.736 -                    out.append("; continue; }");
   1.737 +                    emit(out, "if (@1 >= 0) { gt = @2; continue; }",
   1.738 +                         mapper.popI(), Integer.toString(indx));
   1.739                      i += 2;
   1.740                      break;
   1.741                  }
   1.742                  case opc_ifnonnull: {
   1.743                      int indx = i + readIntArg(byteCodes, i);
   1.744 -                    out.append("if (").append(mapper.popA())
   1.745 -                                      .append(" !== null) { gt = " + indx);
   1.746 -                    out.append("; continue; }");
   1.747 +                    emit(out, "if (@1 !== null) { gt = @2; continue; }",
   1.748 +                         mapper.popA(), Integer.toString(indx));
   1.749                      i += 2;
   1.750                      break;
   1.751                  }
   1.752                  case opc_ifnull: {
   1.753                      int indx = i + readIntArg(byteCodes, i);
   1.754 -                    out.append("if (").append(mapper.popA())
   1.755 -                                      .append(" === null) { gt = " + indx);
   1.756 -                    out.append("; continue; }");
   1.757 +                    emit(out, "if (@1 === null) { gt = @2; continue; }",
   1.758 +                         mapper.popA(), Integer.toString(indx));
   1.759                      i += 2;
   1.760                      break;
   1.761                  }
   1.762 @@ -896,7 +822,7 @@
   1.763                      break;
   1.764                  case opc_goto: {
   1.765                      int indx = i + readIntArg(byteCodes, i);
   1.766 -                    out.append("gt = " + indx).append("; continue;");
   1.767 +                    emit(out, "gt = @1; continue;", Integer.toString(indx));
   1.768                      i += 2;
   1.769                      break;
   1.770                  }
   1.771 @@ -953,27 +879,22 @@
   1.772                  case opc_new: {
   1.773                      int indx = readIntArg(byteCodes, i);
   1.774                      String ci = jc.getClassName(indx);
   1.775 -                    out.append(mapper.pushA()).append(" = ");
   1.776 -                    out.append("new ").append(ci.replace('/','_'));
   1.777 -                    out.append(';');
   1.778 +                    emit(out, "@1 = new @2;",
   1.779 +                         mapper.pushA(), ci.replace('/', '_'));
   1.780                      addReference(ci);
   1.781                      i += 2;
   1.782                      break;
   1.783                  }
   1.784 -                case opc_newarray: {
   1.785 +                case opc_newarray:
   1.786                      ++i; // skip type of array
   1.787 -                    final Variable v = mapper.popI();
   1.788 -                    out.append(mapper.pushA()).append(" = ")
   1.789 -                       .append("new Array(").append(v).append(").fillNulls();");
   1.790 +                    emit(out, "@2 = new Array(@1).fillNulls();",
   1.791 +                         mapper.popI(), mapper.pushA());
   1.792                      break;
   1.793 -                }
   1.794 -                case opc_anewarray: {
   1.795 +                case opc_anewarray:
   1.796                      i += 2; // skip type of array
   1.797 -                    final Variable v = mapper.popI();
   1.798 -                    out.append(mapper.pushA()).append(" = ")
   1.799 -                       .append("new Array(").append(v).append(").fillNulls();");
   1.800 +                    emit(out, "@2 = new Array(@1).fillNulls();",
   1.801 +                         mapper.popI(), mapper.pushA());
   1.802                      break;
   1.803 -                }
   1.804                  case opc_multianewarray: {
   1.805                      i += 2;
   1.806                      int dim = readByte(byteCodes, ++i);
   1.807 @@ -996,93 +917,55 @@
   1.808                      out.append("\n").append(mapper.pushA()).append(" = a0; }");
   1.809                      break;
   1.810                  }
   1.811 -                case opc_arraylength: {
   1.812 -                    final Variable v = mapper.popA();
   1.813 -                    out.append(mapper.pushI()).append(" = ")
   1.814 -                       .append(v).append(".length;");
   1.815 +                case opc_arraylength:
   1.816 +                    emit(out, "@2 = @1.length;", mapper.popA(), mapper.pushI());
   1.817                      break;
   1.818 -                }
   1.819 -                case opc_lastore: {
   1.820 -                    out.append(mapper.getA(2)).append('[')
   1.821 -                                              .append(mapper.getI(1))
   1.822 -                                              .append(']')
   1.823 -                       .append(" = ").append(mapper.getL(0)).append(';');
   1.824 -                    mapper.pop(3);
   1.825 +                case opc_lastore:
   1.826 +                    emit(out, "@3[@2] = @1;",
   1.827 +                         mapper.popL(), mapper.popI(), mapper.popA());
   1.828                      break;
   1.829 -                }
   1.830 -                case opc_fastore: {
   1.831 -                    out.append(mapper.getA(2)).append('[')
   1.832 -                                              .append(mapper.getI(1))
   1.833 -                                              .append(']')
   1.834 -                       .append(" = ").append(mapper.getF(0)).append(';');
   1.835 -                    mapper.pop(3);
   1.836 +                case opc_fastore:
   1.837 +                    emit(out, "@3[@2] = @1;",
   1.838 +                         mapper.popF(), mapper.popI(), mapper.popA());
   1.839                      break;
   1.840 -                }
   1.841 -                case opc_dastore: {
   1.842 -                    out.append(mapper.getA(2)).append('[')
   1.843 -                                              .append(mapper.getI(1))
   1.844 -                                              .append(']')
   1.845 -                       .append(" = ").append(mapper.getD(0)).append(';');
   1.846 -                    mapper.pop(3);
   1.847 +                case opc_dastore:
   1.848 +                    emit(out, "@3[@2] = @1;",
   1.849 +                         mapper.popD(), mapper.popI(), mapper.popA());
   1.850                      break;
   1.851 -                }
   1.852 -                case opc_aastore: {
   1.853 -                    out.append(mapper.getA(2)).append('[')
   1.854 -                                              .append(mapper.getI(1))
   1.855 -                                              .append(']')
   1.856 -                       .append(" = ").append(mapper.getA(0)).append(';');
   1.857 -                    mapper.pop(3);
   1.858 +                case opc_aastore:
   1.859 +                    emit(out, "@3[@2] = @1;",
   1.860 +                         mapper.popA(), mapper.popI(), mapper.popA());
   1.861                      break;
   1.862 -                }
   1.863                  case opc_iastore:
   1.864                  case opc_bastore:
   1.865                  case opc_castore:
   1.866 -                case opc_sastore: {
   1.867 -                    out.append(mapper.getA(2)).append('[')
   1.868 -                                              .append(mapper.getI(1))
   1.869 -                                              .append(']')
   1.870 -                       .append(" = ").append(mapper.getI(0)).append(';');
   1.871 -                    mapper.pop(3);
   1.872 +                case opc_sastore:
   1.873 +                    emit(out, "@3[@2] = @1;",
   1.874 +                         mapper.popI(), mapper.popI(), mapper.popA());
   1.875                      break;
   1.876 -                }
   1.877 -                case opc_laload: {
   1.878 -                    final Variable vidx = mapper.popI();
   1.879 -                    final Variable varr = mapper.popA();
   1.880 -                    out.append(mapper.pushL()).append(" = ")
   1.881 -                       .append(varr).append('[').append(vidx).append("];");
   1.882 +                case opc_laload:
   1.883 +                    emit(out, "@3 = @2[@1];",
   1.884 +                         mapper.popI(), mapper.popA(), mapper.pushL());
   1.885                      break;
   1.886 -                }
   1.887 -                case opc_faload: {
   1.888 -                    final Variable vidx = mapper.popI();
   1.889 -                    final Variable varr = mapper.popA();
   1.890 -                    out.append(mapper.pushF()).append(" = ")
   1.891 -                       .append(varr).append('[').append(vidx).append("];");
   1.892 +                case opc_faload:
   1.893 +                    emit(out, "@3 = @2[@1];",
   1.894 +                         mapper.popI(), mapper.popA(), mapper.pushF());
   1.895                      break;
   1.896 -                }
   1.897 -                case opc_daload: {
   1.898 -                    final Variable vidx = mapper.popI();
   1.899 -                    final Variable varr = mapper.popA();
   1.900 -                    out.append(mapper.pushD()).append(" = ")
   1.901 -                       .append(varr).append('[').append(vidx).append("];");
   1.902 +                case opc_daload:
   1.903 +                    emit(out, "@3 = @2[@1];",
   1.904 +                         mapper.popI(), mapper.popA(), mapper.pushD());
   1.905                      break;
   1.906 -                }
   1.907 -                case opc_aaload: {
   1.908 -                    final Variable vidx = mapper.popI();
   1.909 -                    final Variable varr = mapper.popA();
   1.910 -                    out.append(mapper.pushA()).append(" = ")
   1.911 -                       .append(varr).append('[').append(vidx).append("];");
   1.912 +                case opc_aaload:
   1.913 +                    emit(out, "@3 = @2[@1];",
   1.914 +                         mapper.popI(), mapper.popA(), mapper.pushA());
   1.915                      break;
   1.916 -                }
   1.917                  case opc_iaload:
   1.918                  case opc_baload:
   1.919                  case opc_caload:
   1.920 -                case opc_saload: {
   1.921 -                    final Variable vidx = mapper.popI();
   1.922 -                    final Variable varr = mapper.popA();
   1.923 -                    out.append(mapper.pushI()).append(" = ")
   1.924 -                       .append(varr).append('[').append(vidx).append("];");
   1.925 +                case opc_saload:
   1.926 +                    emit(out, "@3 = @2[@1];",
   1.927 +                         mapper.popI(), mapper.popA(), mapper.pushI());
   1.928                      break;
   1.929 -                }
   1.930                  case opc_pop:
   1.931                  case opc_pop2:
   1.932                      mapper.pop(1);
   1.933 @@ -1090,24 +973,19 @@
   1.934                      break;
   1.935                  case opc_dup: {
   1.936                      final Variable v = mapper.get(0);
   1.937 -                    out.append(mapper.pushT(v.getType())).append(" = ")
   1.938 -                       .append(v).append(';');
   1.939 +                    emit(out, "@1 = @2;", mapper.pushT(v.getType()), v);
   1.940                      break;
   1.941                  }
   1.942                  case opc_dup2: {
   1.943                      if (mapper.get(0).isCategory2()) {
   1.944                          final Variable v = mapper.get(0);
   1.945 -                        out.append(mapper.pushT(v.getType())).append(" = ")
   1.946 -                           .append(v).append(';');
   1.947 +                        emit(out, "@1 = @2;", mapper.pushT(v.getType()), v);
   1.948                      } else {
   1.949                          final Variable v1 = mapper.get(0);
   1.950                          final Variable v2 = mapper.get(1);
   1.951 -                        out.append("{ ");
   1.952 -                        out.append(mapper.pushT(v2.getType())).append(" = ")
   1.953 -                           .append(v2).append("; ");
   1.954 -                        out.append(mapper.pushT(v1.getType())).append(" = ")
   1.955 -                           .append(v1).append("; ");
   1.956 -                        out.append('}');
   1.957 +                        emit(out, "{ @1 = @2; @3 = @4; }",
   1.958 +                             mapper.pushT(v2.getType()), v2,
   1.959 +                             mapper.pushT(v1.getType()), v1);
   1.960                      }
   1.961                      break;
   1.962                  }
   1.963 @@ -1118,11 +996,8 @@
   1.964                      final Variable vo2 = mapper.pushT(vi2.getType());
   1.965                      final Variable vo1 = mapper.pushT(vi1.getType());
   1.966  
   1.967 -                    out.append("{ ");
   1.968 -                    out.append(vo1).append(" = ").append(vi1).append("; ");
   1.969 -                    out.append(vo2).append(" = ").append(vi2).append("; ");
   1.970 -                    out.append(vo3).append(" = ").append(vo1).append("; ");
   1.971 -                    out.append('}');
   1.972 +                    emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
   1.973 +                         vo1, vi1, vo2, vi2, vo3, vo1);
   1.974                      break;
   1.975                  }
   1.976                  case opc_dup_x2: {
   1.977 @@ -1133,11 +1008,8 @@
   1.978                          final Variable vo2 = mapper.pushT(vi2.getType());
   1.979                          final Variable vo1 = mapper.pushT(vi1.getType());
   1.980  
   1.981 -                        out.append("{ ");
   1.982 -                        out.append(vo1).append(" = ").append(vi1).append("; ");
   1.983 -                        out.append(vo2).append(" = ").append(vi2).append("; ");
   1.984 -                        out.append(vo3).append(" = ").append(vo1).append("; ");
   1.985 -                        out.append('}');
   1.986 +                        emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
   1.987 +                             vo1, vi1, vo2, vi2, vo3, vo1);
   1.988                      } else {
   1.989                          final Variable vi1 = mapper.pop();
   1.990                          final Variable vi2 = mapper.pop();
   1.991 @@ -1147,32 +1019,27 @@
   1.992                          final Variable vo2 = mapper.pushT(vi2.getType());
   1.993                          final Variable vo1 = mapper.pushT(vi1.getType());
   1.994  
   1.995 -                        out.append("{ ");
   1.996 -                        out.append(vo1).append(" = ").append(vi1).append("; ");
   1.997 -                        out.append(vo2).append(" = ").append(vi2).append("; ");
   1.998 -                        out.append(vo3).append(" = ").append(vi3).append("; ");
   1.999 -                        out.append(vo4).append(" = ").append(vo1).append("; ");
  1.1000 -                        out.append('}');
  1.1001 +                        emit(out, "{ @1 = @2; @3 = @4; @5 = @6; @7 = @8; }",
  1.1002 +                             vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
  1.1003                      }
  1.1004                      break;
  1.1005                  }
  1.1006                  case opc_bipush:
  1.1007 -                    out.append(mapper.pushI()).append(" = ")
  1.1008 -                       .append(Integer.toString(byteCodes[++i])).append(';');
  1.1009 +                    emit(out, "@1 = @2;",
  1.1010 +                         mapper.pushI(), Integer.toString(byteCodes[++i]));
  1.1011                      break;
  1.1012                  case opc_sipush:
  1.1013 -                    out.append(mapper.pushI()).append(" = ")
  1.1014 -                       .append(Integer.toString(readIntArg(byteCodes, i)))
  1.1015 -                       .append(';');
  1.1016 +                    emit(out, "@1 = @2;",
  1.1017 +                         mapper.pushI(),
  1.1018 +                         Integer.toString(readIntArg(byteCodes, i)));
  1.1019                      i += 2;
  1.1020                      break;
  1.1021                  case opc_getfield: {
  1.1022                      int indx = readIntArg(byteCodes, i);
  1.1023                      String[] fi = jc.getFieldInfoName(indx);
  1.1024                      final int type = fieldToVariableType(fi[2].charAt(0));
  1.1025 -                    final Variable v = mapper.popA();
  1.1026 -                    out.append(mapper.pushT(type)).append(" = ")
  1.1027 -                       .append(v).append(".fld_").append(fi[1]).append(';');
  1.1028 +                    emit(out, "@2 = @1.fld_@3;",
  1.1029 +                         mapper.popA(), mapper.pushT(type), fi[1]);
  1.1030                      i += 2;
  1.1031                      break;
  1.1032                  }
  1.1033 @@ -1180,9 +1047,8 @@
  1.1034                      int indx = readIntArg(byteCodes, i);
  1.1035                      String[] fi = jc.getFieldInfoName(indx);
  1.1036                      final int type = fieldToVariableType(fi[2].charAt(0));
  1.1037 -                    out.append(mapper.pushT(type)).append(" = ")
  1.1038 -                       .append(fi[0].replace('/', '_'))
  1.1039 -                       .append('.').append(fi[1]).append(';');
  1.1040 +                    emit(out, "@1 = @2.@3;",
  1.1041 +                         mapper.pushT(type), fi[0].replace('/', '_'), fi[1]);
  1.1042                      i += 2;
  1.1043                      addReference(fi[0]);
  1.1044                      break;
  1.1045 @@ -1191,9 +1057,8 @@
  1.1046                      int indx = readIntArg(byteCodes, i);
  1.1047                      String[] fi = jc.getFieldInfoName(indx);
  1.1048                      final int type = fieldToVariableType(fi[2].charAt(0));
  1.1049 -                    final Variable v = mapper.popT(type);
  1.1050 -                    out.append(mapper.popA()).append(".fld_").append(fi[1])
  1.1051 -                       .append(" = ").append(v).append(';');
  1.1052 +                    emit(out, "@2.fld_@3 = @1;",
  1.1053 +                         mapper.popT(type), mapper.popA(), fi[1]);
  1.1054                      i += 2;
  1.1055                      break;
  1.1056                  }
  1.1057 @@ -1201,9 +1066,8 @@
  1.1058                      int indx = readIntArg(byteCodes, i);
  1.1059                      String[] fi = jc.getFieldInfoName(indx);
  1.1060                      final int type = fieldToVariableType(fi[2].charAt(0));
  1.1061 -                    out.append(fi[0].replace('/', '_'));
  1.1062 -                    out.append('.').append(fi[1]).append(" = ")
  1.1063 -                       .append(mapper.popT(type)).append(';');
  1.1064 +                    emit(out, "@1.@2 = @3;",
  1.1065 +                         fi[0].replace('/', '_'), fi[1], mapper.popT(type));
  1.1066                      i += 2;
  1.1067                      addReference(fi[0]);
  1.1068                      break;
  1.1069 @@ -1213,9 +1077,9 @@
  1.1070                      final String type = jc.getClassName(indx);
  1.1071                      if (!type.startsWith("[")) {
  1.1072                          // no way to check arrays right now
  1.1073 -                        out.append("if (").append(mapper.getA(0))
  1.1074 -                           .append(".$instOf_").append(type.replace('/', '_'))
  1.1075 -                           .append(" != 1) throw {};"); // XXX proper exception
  1.1076 +                        // XXX proper exception
  1.1077 +                        emit(out, "if (@1.$instOf_@2 != 1) throw {};",
  1.1078 +                             mapper.getA(0), type.replace('/', '_'));
  1.1079                      }
  1.1080                      i += 2;
  1.1081                      break;
  1.1082 @@ -1223,11 +1087,8 @@
  1.1083                  case opc_instanceof: {
  1.1084                      int indx = readIntArg(byteCodes, i);
  1.1085                      final String type = jc.getClassName(indx);
  1.1086 -                    final Variable v = mapper.popA();
  1.1087 -                    out.append(mapper.pushI()).append(" = ")
  1.1088 -                       .append(v).append(".$instOf_")
  1.1089 -                                 .append(type.replace('/', '_'))
  1.1090 -                       .append(" ? 1 : 0;");
  1.1091 +                    emit(out, "@2 = @1.$instOf_@3 ? 1 : 0;",
  1.1092 +                         mapper.popA(), mapper.pushI(), type.replace('/', '_'));
  1.1093                      i += 2;
  1.1094                      break;
  1.1095                  }
  1.1096 @@ -1235,12 +1096,8 @@
  1.1097                      final Variable v = mapper.popA();
  1.1098                      mapper.clear();
  1.1099  
  1.1100 -                    out.append("{ ");
  1.1101 -                    out.append(mapper.pushA()).append(" = ")
  1.1102 -                       .append(v).append("; ");
  1.1103 -                    out.append("throw ").append(v).append("; ");
  1.1104 -                    out.append('}');
  1.1105 -
  1.1106 +                    emit(out, "{ @1 = @2; throw @2; }",
  1.1107 +                         mapper.pushA(), v);
  1.1108                      break;
  1.1109                  }
  1.1110  
  1.1111 @@ -1257,9 +1114,9 @@
  1.1112                  }
  1.1113  
  1.1114                  default: {
  1.1115 -                    out.append("throw 'unknown bytecode " + c + "';");
  1.1116 +                    emit(out, "throw 'unknown bytecode @1';",
  1.1117 +                         Integer.toString(c));
  1.1118                  }
  1.1119 -                    
  1.1120              }
  1.1121              out.append(" //");
  1.1122              for (int j = prev; j <= i; j++) {
  1.1123 @@ -1283,15 +1140,6 @@
  1.1124          return i + 2;
  1.1125      }
  1.1126  
  1.1127 -    private void generateCmp(Variable v2, Variable v1, Variable vr)
  1.1128 -            throws IOException {
  1.1129 -        out.append(vr).append(" = ")
  1.1130 -           .append('(').append(v1).append(" == ").append(v2).append(')')
  1.1131 -           .append(" ? 0")
  1.1132 -           .append(" : ((").append(v1).append(" < ").append(v2).append(')')
  1.1133 -           .append(" ? -1 : 1);");
  1.1134 -    }
  1.1135 -
  1.1136      private int readIntArg(byte[] byteCodes, int offsetInstruction) {
  1.1137          final int indxHi = byteCodes[offsetInstruction + 1] << 8;
  1.1138          final int indxLo = byteCodes[offsetInstruction + 2];
  1.1139 @@ -1718,4 +1566,30 @@
  1.1140                  throw new IllegalStateException("Unhandled field type");
  1.1141          }
  1.1142      }
  1.1143 +
  1.1144 +    private static void emit(final Appendable out,
  1.1145 +                             final String format,
  1.1146 +                             final CharSequence... params) throws IOException {
  1.1147 +        final int length = format.length();
  1.1148 +
  1.1149 +        int processed = 0;
  1.1150 +        int paramOffset = format.indexOf('@');
  1.1151 +        while ((paramOffset != -1) && (paramOffset < (length - 1))) {
  1.1152 +            final char paramChar = format.charAt(paramOffset + 1);
  1.1153 +            if ((paramChar >= '1') && (paramChar <= '9')) {
  1.1154 +                final int paramIndex = paramChar - '0' - 1;
  1.1155 +
  1.1156 +                out.append(format, processed, paramOffset);
  1.1157 +                out.append(params[paramIndex]);
  1.1158 +
  1.1159 +                ++paramOffset;
  1.1160 +                processed = paramOffset + 1;
  1.1161 +            }
  1.1162 +
  1.1163 +            paramOffset = format.indexOf('@', paramOffset + 1);
  1.1164 +        }
  1.1165 +
  1.1166 +        out.append(format, processed, length);
  1.1167 +    }
  1.1168 +
  1.1169  }