1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 03 14:44:49 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 07 15:02:35 2012 +0100
1.3 @@ -241,12 +241,15 @@
1.4 // so this might generate more stack variables than we need
1.5 final int maxStack = m.getMaxStack();
1.6 if (maxStack > 0) {
1.7 - out.append("\n var ").append(mapper.constructVariableName(0));
1.8 - for (int i = 1; i < maxStack; ++i) {
1.9 - out.append(", ");
1.10 - out.append(mapper.constructVariableName(i));
1.11 + // TODO: generate only used stack variables
1.12 + for (int j = 0; j <= Variable.LAST_TYPE; ++j) {
1.13 + out.append("\n var ").append(Variable.getStackVariable(j, 0));
1.14 + for (int i = 1; i < maxStack; ++i) {
1.15 + out.append(", ");
1.16 + out.append(Variable.getStackVariable(j, i));
1.17 + }
1.18 + out.append(';');
1.19 }
1.20 - out.append(';');
1.21 }
1.22
1.23 int lastStackFrame = -1;
1.24 @@ -257,7 +260,7 @@
1.25 stackMapIterator.advanceTo(i);
1.26 if (lastStackFrame != stackMapIterator.getFrameIndex()) {
1.27 lastStackFrame = stackMapIterator.getFrameIndex();
1.28 - mapper.reset(stackMapIterator.getFrameStackItemsCount());
1.29 + mapper.syncWithFrameStack(stackMapIterator.getFrameStack());
1.30 out.append(" case " + i).append(": ");
1.31 } else {
1.32 out.append(" /* " + i).append(" */ ");
1.33 @@ -265,162 +268,330 @@
1.34 final int c = readByte(byteCodes, i);
1.35 switch (c) {
1.36 case opc_aload_0:
1.37 + out.append(mapper.pushA()).append(" = arg0;");
1.38 + break;
1.39 case opc_iload_0:
1.40 + out.append(mapper.pushI()).append(" = arg0;");
1.41 + break;
1.42 case opc_lload_0:
1.43 + out.append(mapper.pushL()).append(" = arg0;");
1.44 + break;
1.45 case opc_fload_0:
1.46 + out.append(mapper.pushF()).append(" = arg0;");
1.47 + break;
1.48 case opc_dload_0:
1.49 - out.append(mapper.push()).append(" = arg0;");
1.50 + out.append(mapper.pushD()).append(" = arg0;");
1.51 break;
1.52 case opc_aload_1:
1.53 + out.append(mapper.pushA()).append(" = arg1;");
1.54 + break;
1.55 case opc_iload_1:
1.56 + out.append(mapper.pushI()).append(" = arg1;");
1.57 + break;
1.58 case opc_lload_1:
1.59 + out.append(mapper.pushL()).append(" = arg1;");
1.60 + break;
1.61 case opc_fload_1:
1.62 + out.append(mapper.pushF()).append(" = arg1;");
1.63 + break;
1.64 case opc_dload_1:
1.65 - out.append(mapper.push()).append(" = arg1;");
1.66 + out.append(mapper.pushD()).append(" = arg1;");
1.67 break;
1.68 case opc_aload_2:
1.69 + out.append(mapper.pushA()).append(" = arg2;");
1.70 + break;
1.71 case opc_iload_2:
1.72 + out.append(mapper.pushI()).append(" = arg2;");
1.73 + break;
1.74 case opc_lload_2:
1.75 + out.append(mapper.pushL()).append(" = arg2;");
1.76 + break;
1.77 case opc_fload_2:
1.78 + out.append(mapper.pushF()).append(" = arg2;");
1.79 + break;
1.80 case opc_dload_2:
1.81 - out.append(mapper.push()).append(" = arg2;");
1.82 + out.append(mapper.pushD()).append(" = arg2;");
1.83 break;
1.84 case opc_aload_3:
1.85 + out.append(mapper.pushA()).append(" = arg3;");
1.86 + break;
1.87 case opc_iload_3:
1.88 + out.append(mapper.pushI()).append(" = arg3;");
1.89 + break;
1.90 case opc_lload_3:
1.91 + out.append(mapper.pushL()).append(" = arg3;");
1.92 + break;
1.93 case opc_fload_3:
1.94 + out.append(mapper.pushF()).append(" = arg3;");
1.95 + break;
1.96 case opc_dload_3:
1.97 - out.append(mapper.push()).append(" = arg3;");
1.98 + out.append(mapper.pushD()).append(" = arg3;");
1.99 break;
1.100 - case opc_iload:
1.101 - case opc_lload:
1.102 - case opc_fload:
1.103 - case opc_dload:
1.104 + case opc_iload: {
1.105 + final int indx = readByte(byteCodes, ++i);
1.106 + out.append(mapper.pushI()).append(" = ")
1.107 + .append("arg").append(indx + ";");
1.108 + break;
1.109 + }
1.110 + case opc_lload: {
1.111 + final int indx = readByte(byteCodes, ++i);
1.112 + out.append(mapper.pushL()).append(" = ")
1.113 + .append("arg").append(indx + ";");
1.114 + break;
1.115 + }
1.116 + case opc_fload: {
1.117 + final int indx = readByte(byteCodes, ++i);
1.118 + out.append(mapper.pushF()).append(" = ")
1.119 + .append("arg").append(indx + ";");
1.120 + break;
1.121 + }
1.122 + case opc_dload: {
1.123 + final int indx = readByte(byteCodes, ++i);
1.124 + out.append(mapper.pushD()).append(" = ")
1.125 + .append("arg").append(indx + ";");
1.126 + break;
1.127 + }
1.128 case opc_aload: {
1.129 final int indx = readByte(byteCodes, ++i);
1.130 - out.append(mapper.push())
1.131 - .append(" = arg")
1.132 - .append(indx + ";");
1.133 + out.append(mapper.pushA()).append(" = ")
1.134 + .append("arg").append(indx + ";");
1.135 break;
1.136 }
1.137 - case opc_istore:
1.138 - case opc_lstore:
1.139 - case opc_fstore:
1.140 - case opc_dstore:
1.141 + case opc_istore: {
1.142 + final int indx = readByte(byteCodes, ++i);
1.143 + out.append("arg" + indx).append(" = ")
1.144 + .append(mapper.popI()).append(';');
1.145 + break;
1.146 + }
1.147 + case opc_lstore: {
1.148 + final int indx = readByte(byteCodes, ++i);
1.149 + out.append("arg" + indx).append(" = ")
1.150 + .append(mapper.popL()).append(';');
1.151 + break;
1.152 + }
1.153 + case opc_fstore: {
1.154 + final int indx = readByte(byteCodes, ++i);
1.155 + out.append("arg" + indx).append(" = ")
1.156 + .append(mapper.popF()).append(';');
1.157 + break;
1.158 + }
1.159 + case opc_dstore: {
1.160 + final int indx = readByte(byteCodes, ++i);
1.161 + out.append("arg" + indx).append(" = ")
1.162 + .append(mapper.popD()).append(';');
1.163 + break;
1.164 + }
1.165 case opc_astore: {
1.166 final int indx = readByte(byteCodes, ++i);
1.167 - out.append("arg" + indx)
1.168 - .append(" = ")
1.169 - .append(mapper.pop())
1.170 - .append(';');
1.171 + out.append("arg" + indx).append(" = ")
1.172 + .append(mapper.popA()).append(';');
1.173 break;
1.174 }
1.175 case opc_astore_0:
1.176 + out.append("arg0 = ").append(mapper.popA()).append(';');
1.177 + break;
1.178 case opc_istore_0:
1.179 + out.append("arg0 = ").append(mapper.popI()).append(';');
1.180 + break;
1.181 case opc_lstore_0:
1.182 + out.append("arg0 = ").append(mapper.popL()).append(';');
1.183 + break;
1.184 case opc_fstore_0:
1.185 + out.append("arg0 = ").append(mapper.popF()).append(';');
1.186 + break;
1.187 case opc_dstore_0:
1.188 - out.append("arg0 = ").append(mapper.pop()).append(';');
1.189 + out.append("arg0 = ").append(mapper.popD()).append(';');
1.190 break;
1.191 case opc_astore_1:
1.192 + out.append("arg1 = ").append(mapper.popA()).append(';');
1.193 + break;
1.194 case opc_istore_1:
1.195 + out.append("arg1 = ").append(mapper.popI()).append(';');
1.196 + break;
1.197 case opc_lstore_1:
1.198 + out.append("arg1 = ").append(mapper.popL()).append(';');
1.199 + break;
1.200 case opc_fstore_1:
1.201 + out.append("arg1 = ").append(mapper.popF()).append(';');
1.202 + break;
1.203 case opc_dstore_1:
1.204 - out.append("arg1 = ").append(mapper.pop()).append(';');
1.205 + out.append("arg1 = ").append(mapper.popD()).append(';');
1.206 break;
1.207 case opc_astore_2:
1.208 + out.append("arg2 = ").append(mapper.popA()).append(';');
1.209 + break;
1.210 case opc_istore_2:
1.211 + out.append("arg2 = ").append(mapper.popI()).append(';');
1.212 + break;
1.213 case opc_lstore_2:
1.214 + out.append("arg2 = ").append(mapper.popL()).append(';');
1.215 + break;
1.216 case opc_fstore_2:
1.217 + out.append("arg2 = ").append(mapper.popF()).append(';');
1.218 + break;
1.219 case opc_dstore_2:
1.220 - out.append("arg2 = ").append(mapper.pop()).append(';');
1.221 + out.append("arg2 = ").append(mapper.popD()).append(';');
1.222 break;
1.223 case opc_astore_3:
1.224 + out.append("arg3 = ").append(mapper.popA()).append(';');
1.225 + break;
1.226 case opc_istore_3:
1.227 + out.append("arg3 = ").append(mapper.popI()).append(';');
1.228 + break;
1.229 case opc_lstore_3:
1.230 + out.append("arg3 = ").append(mapper.popL()).append(';');
1.231 + break;
1.232 case opc_fstore_3:
1.233 + out.append("arg3 = ").append(mapper.popF()).append(';');
1.234 + break;
1.235 case opc_dstore_3:
1.236 - out.append("arg3 = ").append(mapper.pop()).append(';');
1.237 + out.append("arg3 = ").append(mapper.popD()).append(';');
1.238 break;
1.239 case opc_iadd:
1.240 + out.append(mapper.getI(1)).append(" += ")
1.241 + .append(mapper.popI()).append(';');
1.242 + break;
1.243 case opc_ladd:
1.244 + out.append(mapper.getL(1)).append(" += ")
1.245 + .append(mapper.popL()).append(';');
1.246 + break;
1.247 case opc_fadd:
1.248 + out.append(mapper.getF(1)).append(" += ")
1.249 + .append(mapper.popF()).append(';');
1.250 + break;
1.251 case opc_dadd:
1.252 - out.append(mapper.get(1)).append(" += ")
1.253 - .append(mapper.pop()).append(';');
1.254 + out.append(mapper.getD(1)).append(" += ")
1.255 + .append(mapper.popD()).append(';');
1.256 break;
1.257 case opc_isub:
1.258 + out.append(mapper.getI(1)).append(" -= ")
1.259 + .append(mapper.popI()).append(';');
1.260 + break;
1.261 case opc_lsub:
1.262 + out.append(mapper.getL(1)).append(" -= ")
1.263 + .append(mapper.popL()).append(';');
1.264 + break;
1.265 case opc_fsub:
1.266 + out.append(mapper.getF(1)).append(" -= ")
1.267 + .append(mapper.popF()).append(';');
1.268 + break;
1.269 case opc_dsub:
1.270 - out.append(mapper.get(1)).append(" -= ")
1.271 - .append(mapper.pop()).append(';');
1.272 + out.append(mapper.getD(1)).append(" -= ")
1.273 + .append(mapper.popD()).append(';');
1.274 break;
1.275 case opc_imul:
1.276 + out.append(mapper.getI(1)).append(" *= ")
1.277 + .append(mapper.popI()).append(';');
1.278 + break;
1.279 case opc_lmul:
1.280 + out.append(mapper.getL(1)).append(" *= ")
1.281 + .append(mapper.popL()).append(';');
1.282 + break;
1.283 case opc_fmul:
1.284 + out.append(mapper.getF(1)).append(" *= ")
1.285 + .append(mapper.popF()).append(';');
1.286 + break;
1.287 case opc_dmul:
1.288 - out.append(mapper.get(1)).append(" *= ")
1.289 - .append(mapper.pop()).append(';');
1.290 + out.append(mapper.getD(1)).append(" *= ")
1.291 + .append(mapper.popD()).append(';');
1.292 break;
1.293 case opc_idiv:
1.294 + out.append(mapper.getI(1)).append(" = ")
1.295 + .append("Math.floor(").append(mapper.getI(1))
1.296 + .append(" / ").append(mapper.popI()).append(");");
1.297 + break;
1.298 case opc_ldiv:
1.299 - out.append(mapper.get(1))
1.300 - .append(" = Math.floor(")
1.301 - .append(mapper.get(1))
1.302 - .append(" / ")
1.303 - .append(mapper.pop())
1.304 - .append(");");
1.305 + out.append(mapper.getL(1)).append(" = ")
1.306 + .append("Math.floor(").append(mapper.getL(1))
1.307 + .append(" / ").append(mapper.popL()).append(");");
1.308 break;
1.309 case opc_fdiv:
1.310 + out.append(mapper.getF(1)).append(" /= ")
1.311 + .append(mapper.popF()).append(';');
1.312 + break;
1.313 case opc_ddiv:
1.314 - out.append(mapper.get(1)).append(" /= ")
1.315 - .append(mapper.pop()).append(';');
1.316 + out.append(mapper.getD(1)).append(" /= ")
1.317 + .append(mapper.popD()).append(';');
1.318 break;
1.319 case opc_irem:
1.320 + out.append(mapper.getI(1)).append(" %= ")
1.321 + .append(mapper.popI()).append(';');
1.322 + break;
1.323 case opc_lrem:
1.324 + out.append(mapper.getL(1)).append(" %= ")
1.325 + .append(mapper.popL()).append(';');
1.326 + break;
1.327 case opc_frem:
1.328 + out.append(mapper.getF(1)).append(" %= ")
1.329 + .append(mapper.popF()).append(';');
1.330 + break;
1.331 case opc_drem:
1.332 - out.append(mapper.get(1)).append(" %= ")
1.333 - .append(mapper.pop()).append(';');
1.334 + out.append(mapper.getD(1)).append(" %= ")
1.335 + .append(mapper.popD()).append(';');
1.336 break;
1.337 case opc_iand:
1.338 + out.append(mapper.getI(1)).append(" &= ")
1.339 + .append(mapper.popI()).append(';');
1.340 + break;
1.341 case opc_land:
1.342 - out.append(mapper.get(1)).append(" &= ")
1.343 - .append(mapper.pop()).append(';');
1.344 + out.append(mapper.getL(1)).append(" &= ")
1.345 + .append(mapper.popL()).append(';');
1.346 break;
1.347 case opc_ior:
1.348 + out.append(mapper.getI(1)).append(" |= ")
1.349 + .append(mapper.popI()).append(';');
1.350 + break;
1.351 case opc_lor:
1.352 - out.append(mapper.get(1)).append(" |= ")
1.353 - .append(mapper.pop()).append(';');
1.354 + out.append(mapper.getL(1)).append(" |= ")
1.355 + .append(mapper.popL()).append(';');
1.356 break;
1.357 case opc_ixor:
1.358 + out.append(mapper.getI(1)).append(" ^= ")
1.359 + .append(mapper.popI()).append(';');
1.360 + break;
1.361 case opc_lxor:
1.362 - out.append(mapper.get(1)).append(" ^= ")
1.363 - .append(mapper.pop()).append(';');
1.364 + out.append(mapper.getL(1)).append(" ^= ")
1.365 + .append(mapper.popL()).append(';');
1.366 break;
1.367 case opc_ineg:
1.368 + out.append(mapper.getI(0)).append(" = -")
1.369 + .append(mapper.getI(0)).append(';');
1.370 + break;
1.371 case opc_lneg:
1.372 + out.append(mapper.getL(0)).append(" = -")
1.373 + .append(mapper.getL(0)).append(';');
1.374 + break;
1.375 case opc_fneg:
1.376 + out.append(mapper.getF(0)).append(" = -")
1.377 + .append(mapper.getF(0)).append(';');
1.378 + break;
1.379 case opc_dneg:
1.380 - out.append(mapper.get(0)).append(" = -")
1.381 - .append(mapper.get(0)).append(';');
1.382 + out.append(mapper.getD(0)).append(" = -")
1.383 + .append(mapper.getD(0)).append(';');
1.384 break;
1.385 case opc_ishl:
1.386 + out.append(mapper.getI(1)).append(" <<= ")
1.387 + .append(mapper.popI()).append(';');
1.388 + break;
1.389 case opc_lshl:
1.390 - out.append(mapper.get(1)).append(" <<= ")
1.391 - .append(mapper.pop()).append(';');
1.392 + out.append(mapper.getL(1)).append(" <<= ")
1.393 + .append(mapper.popI()).append(';');
1.394 break;
1.395 case opc_ishr:
1.396 + out.append(mapper.getI(1)).append(" >>= ")
1.397 + .append(mapper.popI()).append(';');
1.398 + break;
1.399 case opc_lshr:
1.400 - out.append(mapper.get(1)).append(" >>= ")
1.401 - .append(mapper.pop()).append(';');
1.402 + out.append(mapper.getL(1)).append(" >>= ")
1.403 + .append(mapper.popI()).append(';');
1.404 break;
1.405 case opc_iushr:
1.406 + out.append(mapper.getI(1)).append(" >>>= ")
1.407 + .append(mapper.popI()).append(';');
1.408 + break;
1.409 case opc_lushr:
1.410 - out.append(mapper.get(1)).append(" >>>= ")
1.411 - .append(mapper.pop()).append(';');
1.412 + out.append(mapper.getL(1)).append(" >>>= ")
1.413 + .append(mapper.popI()).append(';');
1.414 break;
1.415 case opc_iinc: {
1.416 final int varIndx = readByte(byteCodes, ++i);
1.417 @@ -436,75 +607,149 @@
1.418 out.append("return;");
1.419 break;
1.420 case opc_ireturn:
1.421 + out.append("return ").append(mapper.popI()).append(';');
1.422 + break;
1.423 case opc_lreturn:
1.424 + out.append("return ").append(mapper.popL()).append(';');
1.425 + break;
1.426 case opc_freturn:
1.427 + out.append("return ").append(mapper.popF()).append(';');
1.428 + break;
1.429 case opc_dreturn:
1.430 + out.append("return ").append(mapper.popD()).append(';');
1.431 + break;
1.432 case opc_areturn:
1.433 - out.append("return ").append(mapper.pop()).append(';');
1.434 + out.append("return ").append(mapper.popA()).append(';');
1.435 break;
1.436 - case opc_i2l:
1.437 - case opc_i2f:
1.438 - case opc_i2d:
1.439 - case opc_l2i:
1.440 + case opc_i2l: {
1.441 + final Variable v = mapper.popI();
1.442 + out.append(mapper.pushL()).append(" = ")
1.443 + .append(v).append(';');
1.444 + break;
1.445 + }
1.446 + case opc_i2f: {
1.447 + final Variable v = mapper.popI();
1.448 + out.append(mapper.pushF()).append(" = ")
1.449 + .append(v).append(';');
1.450 + break;
1.451 + }
1.452 + case opc_i2d: {
1.453 + final Variable v = mapper.popI();
1.454 + out.append(mapper.pushD()).append(" = ")
1.455 + .append(v).append(';');
1.456 + break;
1.457 + }
1.458 + case opc_l2i: {
1.459 + final Variable v = mapper.popL();
1.460 + out.append(mapper.pushI()).append(" = ")
1.461 + .append(v).append(';');
1.462 + break;
1.463 + }
1.464 // max int check?
1.465 - case opc_l2f:
1.466 - case opc_l2d:
1.467 - case opc_f2d:
1.468 - case opc_d2f:
1.469 - out.append("/* number conversion */");
1.470 + case opc_l2f: {
1.471 + final Variable v = mapper.popL();
1.472 + out.append(mapper.pushF()).append(" = ")
1.473 + .append(v).append(';');
1.474 break;
1.475 - case opc_f2i:
1.476 - case opc_f2l:
1.477 - case opc_d2i:
1.478 - case opc_d2l:
1.479 - out.append(mapper.get(0))
1.480 - .append(" = Math.floor(")
1.481 - .append(mapper.get(0))
1.482 - .append(");");
1.483 + }
1.484 + case opc_l2d: {
1.485 + final Variable v = mapper.popL();
1.486 + out.append(mapper.pushD()).append(" = ")
1.487 + .append(v).append(';');
1.488 break;
1.489 + }
1.490 + case opc_f2d: {
1.491 + final Variable v = mapper.popF();
1.492 + out.append(mapper.pushD()).append(" = ")
1.493 + .append(v).append(';');
1.494 + break;
1.495 + }
1.496 + case opc_d2f: {
1.497 + final Variable v = mapper.popD();
1.498 + out.append(mapper.pushF()).append(" = ")
1.499 + .append(v).append(';');
1.500 + break;
1.501 + }
1.502 + case opc_f2i: {
1.503 + final Variable v = mapper.popF();
1.504 + out.append(mapper.pushI()).append(" = ")
1.505 + .append("Math.floor(").append(v).append(");");
1.506 + break;
1.507 + }
1.508 + case opc_f2l: {
1.509 + final Variable v = mapper.popF();
1.510 + out.append(mapper.pushL()).append(" = ")
1.511 + .append("Math.floor(").append(v).append(");");
1.512 + break;
1.513 + }
1.514 + case opc_d2i: {
1.515 + final Variable v = mapper.popD();
1.516 + out.append(mapper.pushI()).append(" = ")
1.517 + .append("Math.floor(").append(v).append(");");
1.518 + break;
1.519 + }
1.520 + case opc_d2l: {
1.521 + final Variable v = mapper.popD();
1.522 + out.append(mapper.pushL()).append(" = ")
1.523 + .append("Math.floor(").append(v).append(");");
1.524 + break;
1.525 + }
1.526 case opc_i2b:
1.527 case opc_i2c:
1.528 case opc_i2s:
1.529 out.append("/* number conversion */");
1.530 break;
1.531 case opc_aconst_null:
1.532 - out.append(mapper.push()).append(" = null;");
1.533 + out.append(mapper.pushA()).append(" = null;");
1.534 break;
1.535 case opc_iconst_m1:
1.536 - out.append(mapper.push()).append(" = -1;");
1.537 + out.append(mapper.pushI()).append(" = -1;");
1.538 break;
1.539 case opc_iconst_0:
1.540 + out.append(mapper.pushI()).append(" = 0;");
1.541 + break;
1.542 case opc_dconst_0:
1.543 + out.append(mapper.pushD()).append(" = 0;");
1.544 + break;
1.545 case opc_lconst_0:
1.546 + out.append(mapper.pushL()).append(" = 0;");
1.547 + break;
1.548 case opc_fconst_0:
1.549 - out.append(mapper.push()).append(" = 0;");
1.550 + out.append(mapper.pushF()).append(" = 0;");
1.551 break;
1.552 case opc_iconst_1:
1.553 + out.append(mapper.pushI()).append(" = 1;");
1.554 + break;
1.555 case opc_lconst_1:
1.556 + out.append(mapper.pushL()).append(" = 1;");
1.557 + break;
1.558 case opc_fconst_1:
1.559 + out.append(mapper.pushF()).append(" = 1;");
1.560 + break;
1.561 case opc_dconst_1:
1.562 - out.append(mapper.push()).append(" = 1;");
1.563 + out.append(mapper.pushD()).append(" = 1;");
1.564 break;
1.565 case opc_iconst_2:
1.566 + out.append(mapper.pushI()).append(" = 2;");
1.567 + break;
1.568 case opc_fconst_2:
1.569 - out.append(mapper.push()).append(" = 2;");
1.570 + out.append(mapper.pushF()).append(" = 2;");
1.571 break;
1.572 case opc_iconst_3:
1.573 - out.append(mapper.push()).append(" = 3;");
1.574 + out.append(mapper.pushI()).append(" = 3;");
1.575 break;
1.576 case opc_iconst_4:
1.577 - out.append(mapper.push()).append(" = 4;");
1.578 + out.append(mapper.pushI()).append(" = 4;");
1.579 break;
1.580 case opc_iconst_5:
1.581 - out.append(mapper.push()).append(" = 5;");
1.582 + out.append(mapper.pushI()).append(" = 5;");
1.583 break;
1.584 case opc_ldc: {
1.585 int indx = readByte(byteCodes, ++i);
1.586 String v = encodeConstant(indx);
1.587 - out.append(mapper.push())
1.588 - .append(" = ")
1.589 - .append(v)
1.590 - .append(';');
1.591 + int type = constantToVariableType(jc.getTag(indx));
1.592 + out.append(mapper.pushT(type)).append(" = ")
1.593 + .append(v).append(';');
1.594 break;
1.595 }
1.596 case opc_ldc_w:
1.597 @@ -512,44 +757,38 @@
1.598 int indx = readIntArg(byteCodes, i);
1.599 i += 2;
1.600 String v = encodeConstant(indx);
1.601 - out.append(mapper.push())
1.602 - .append(" = ")
1.603 - .append(v)
1.604 - .append(';');
1.605 + int type = constantToVariableType(jc.getTag(indx));
1.606 + out.append(mapper.pushT(type)).append(" = ")
1.607 + .append(v).append(';');
1.608 break;
1.609 }
1.610 case opc_lcmp:
1.611 + generateCmp(mapper.popL(), mapper.popL(), mapper.pushI());
1.612 + break;
1.613 case opc_fcmpl:
1.614 case opc_fcmpg:
1.615 + generateCmp(mapper.popF(), mapper.popF(), mapper.pushI());
1.616 + break;
1.617 case opc_dcmpl:
1.618 - case opc_dcmpg: {
1.619 - out.append(mapper.get(1))
1.620 - .append(" = (")
1.621 - .append(mapper.get(1))
1.622 - .append(" == ")
1.623 - .append(mapper.get(0))
1.624 - .append(") ? 0 : ((")
1.625 - .append(mapper.get(1))
1.626 - .append(" < ")
1.627 - .append(mapper.get(0))
1.628 - .append(") ? -1 : 1);");
1.629 -
1.630 - mapper.pop(1);
1.631 + case opc_dcmpg:
1.632 + generateCmp(mapper.popD(), mapper.popD(), mapper.pushI());
1.633 break;
1.634 - }
1.635 case opc_if_acmpeq:
1.636 - i = generateIf(byteCodes, i, mapper, "===");
1.637 + i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
1.638 + "===");
1.639 break;
1.640 case opc_if_acmpne:
1.641 - i = generateIf(byteCodes, i, mapper, "!=");
1.642 + i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
1.643 + "!=");
1.644 break;
1.645 case opc_if_icmpeq: {
1.646 - i = generateIf(byteCodes, i, mapper, "==");
1.647 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.648 + "==");
1.649 break;
1.650 }
1.651 case opc_ifeq: {
1.652 int indx = i + readIntArg(byteCodes, i);
1.653 - out.append("if (").append(mapper.pop())
1.654 + out.append("if (").append(mapper.popI())
1.655 .append(" == 0) { gt = " + indx);
1.656 out.append("; continue; }");
1.657 i += 2;
1.658 @@ -557,7 +796,7 @@
1.659 }
1.660 case opc_ifne: {
1.661 int indx = i + readIntArg(byteCodes, i);
1.662 - out.append("if (").append(mapper.pop())
1.663 + out.append("if (").append(mapper.popI())
1.664 .append(" != 0) { gt = " + indx);
1.665 out.append("; continue; }");
1.666 i += 2;
1.667 @@ -565,7 +804,7 @@
1.668 }
1.669 case opc_iflt: {
1.670 int indx = i + readIntArg(byteCodes, i);
1.671 - out.append("if (").append(mapper.pop())
1.672 + out.append("if (").append(mapper.popI())
1.673 .append(" < 0) { gt = " + indx);
1.674 out.append("; continue; }");
1.675 i += 2;
1.676 @@ -573,7 +812,7 @@
1.677 }
1.678 case opc_ifle: {
1.679 int indx = i + readIntArg(byteCodes, i);
1.680 - out.append("if (").append(mapper.pop())
1.681 + out.append("if (").append(mapper.popI())
1.682 .append(" <= 0) { gt = " + indx);
1.683 out.append("; continue; }");
1.684 i += 2;
1.685 @@ -581,7 +820,7 @@
1.686 }
1.687 case opc_ifgt: {
1.688 int indx = i + readIntArg(byteCodes, i);
1.689 - out.append("if (").append(mapper.pop())
1.690 + out.append("if (").append(mapper.popI())
1.691 .append(" > 0) { gt = " + indx);
1.692 out.append("; continue; }");
1.693 i += 2;
1.694 @@ -589,7 +828,7 @@
1.695 }
1.696 case opc_ifge: {
1.697 int indx = i + readIntArg(byteCodes, i);
1.698 - out.append("if (").append(mapper.pop())
1.699 + out.append("if (").append(mapper.popI())
1.700 .append(" >= 0) { gt = " + indx);
1.701 out.append("; continue; }");
1.702 i += 2;
1.703 @@ -597,7 +836,7 @@
1.704 }
1.705 case opc_ifnonnull: {
1.706 int indx = i + readIntArg(byteCodes, i);
1.707 - out.append("if (").append(mapper.pop())
1.708 + out.append("if (").append(mapper.popA())
1.709 .append(" !== null) { gt = " + indx);
1.710 out.append("; continue; }");
1.711 i += 2;
1.712 @@ -605,26 +844,31 @@
1.713 }
1.714 case opc_ifnull: {
1.715 int indx = i + readIntArg(byteCodes, i);
1.716 - out.append("if (").append(mapper.pop())
1.717 + out.append("if (").append(mapper.popA())
1.718 .append(" === null) { gt = " + indx);
1.719 out.append("; continue; }");
1.720 i += 2;
1.721 break;
1.722 }
1.723 case opc_if_icmpne:
1.724 - i = generateIf(byteCodes, i, mapper, "!=");
1.725 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.726 + "!=");
1.727 break;
1.728 case opc_if_icmplt:
1.729 - i = generateIf(byteCodes, i, mapper, "<");
1.730 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.731 + "<");
1.732 break;
1.733 case opc_if_icmple:
1.734 - i = generateIf(byteCodes, i, mapper, "<=");
1.735 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.736 + "<=");
1.737 break;
1.738 case opc_if_icmpgt:
1.739 - i = generateIf(byteCodes, i, mapper, ">");
1.740 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.741 + ">");
1.742 break;
1.743 case opc_if_icmpge:
1.744 - i = generateIf(byteCodes, i, mapper, ">=");
1.745 + i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
1.746 + ">=");
1.747 break;
1.748 case opc_goto: {
1.749 int indx = i + readIntArg(byteCodes, i);
1.750 @@ -638,7 +882,7 @@
1.751 table += 4;
1.752 int n = readInt4(byteCodes, table);
1.753 table += 4;
1.754 - out.append("switch (").append(mapper.pop()).append(") {\n");
1.755 + out.append("switch (").append(mapper.popI()).append(") {\n");
1.756 while (n-- > 0) {
1.757 int cnstnt = readInt4(byteCodes, table);
1.758 table += 4;
1.759 @@ -658,7 +902,7 @@
1.760 table += 4;
1.761 int high = readInt4(byteCodes, table);
1.762 table += 4;
1.763 - out.append("switch (").append(mapper.pop()).append(") {\n");
1.764 + out.append("switch (").append(mapper.popI()).append(") {\n");
1.765 while (low <= high) {
1.766 int offset = i + readInt4(byteCodes, table);
1.767 table += 4;
1.768 @@ -685,7 +929,7 @@
1.769 case opc_new: {
1.770 int indx = readIntArg(byteCodes, i);
1.771 String ci = jc.getClassName(indx);
1.772 - out.append(mapper.push()).append(" = ");
1.773 + out.append(mapper.pushA()).append(" = ");
1.774 out.append("new ").append(ci.replace('/','_'));
1.775 out.append(';');
1.776 addReference(ci);
1.777 @@ -694,28 +938,26 @@
1.778 }
1.779 case opc_newarray: {
1.780 ++i; // skip type of array
1.781 - out.append(mapper.get(0))
1.782 - .append(" = new Array(")
1.783 - .append(mapper.get(0))
1.784 - .append(").fillNulls();");
1.785 + final Variable v = mapper.popI();
1.786 + out.append(mapper.pushA()).append(" = ")
1.787 + .append("new Array(").append(v).append(").fillNulls();");
1.788 break;
1.789 }
1.790 case opc_anewarray: {
1.791 i += 2; // skip type of array
1.792 - out.append(mapper.get(0))
1.793 - .append(" = new Array(")
1.794 - .append(mapper.get(0))
1.795 - .append(").fillNulls();");
1.796 + final Variable v = mapper.popI();
1.797 + out.append(mapper.pushA()).append(" = ")
1.798 + .append("new Array(").append(v).append(").fillNulls();");
1.799 break;
1.800 }
1.801 case opc_multianewarray: {
1.802 i += 2;
1.803 int dim = readByte(byteCodes, ++i);
1.804 - out.append("{ var a0 = new Array(").append(mapper.pop())
1.805 + out.append("{ var a0 = new Array(").append(mapper.popI())
1.806 .append(").fillNulls();");
1.807 for (int d = 1; d < dim; d++) {
1.808 out.append("\n var l" + d).append(" = ")
1.809 - .append(mapper.pop()).append(';');
1.810 + .append(mapper.popI()).append(';');
1.811 out.append("\n for (var i" + d).append (" = 0; i" + d).
1.812 append(" < a" + (d - 1)).
1.813 append(".length; i" + d).append("++) {");
1.814 @@ -727,41 +969,94 @@
1.815 for (int d = 1; d < dim; d++) {
1.816 out.append("\n }");
1.817 }
1.818 - out.append("\n").append(mapper.push()).append(" = a0; }");
1.819 + out.append("\n").append(mapper.pushA()).append(" = a0; }");
1.820 break;
1.821 }
1.822 - case opc_arraylength:
1.823 - out.append(mapper.get(0)).append(" = ")
1.824 - .append(mapper.get(0)).append(".length;");
1.825 + case opc_arraylength: {
1.826 + final Variable v = mapper.popA();
1.827 + out.append(mapper.pushI()).append(" = ")
1.828 + .append(v).append(".length;");
1.829 break;
1.830 + }
1.831 + case opc_lastore: {
1.832 + out.append(mapper.getA(2)).append('[')
1.833 + .append(mapper.getI(1))
1.834 + .append(']')
1.835 + .append(" = ").append(mapper.getL(0)).append(';');
1.836 + mapper.pop(3);
1.837 + break;
1.838 + }
1.839 + case opc_fastore: {
1.840 + out.append(mapper.getA(2)).append('[')
1.841 + .append(mapper.getI(1))
1.842 + .append(']')
1.843 + .append(" = ").append(mapper.getF(0)).append(';');
1.844 + mapper.pop(3);
1.845 + break;
1.846 + }
1.847 + case opc_dastore: {
1.848 + out.append(mapper.getA(2)).append('[')
1.849 + .append(mapper.getI(1))
1.850 + .append(']')
1.851 + .append(" = ").append(mapper.getD(0)).append(';');
1.852 + mapper.pop(3);
1.853 + break;
1.854 + }
1.855 + case opc_aastore: {
1.856 + out.append(mapper.getA(2)).append('[')
1.857 + .append(mapper.getI(1))
1.858 + .append(']')
1.859 + .append(" = ").append(mapper.getA(0)).append(';');
1.860 + mapper.pop(3);
1.861 + break;
1.862 + }
1.863 case opc_iastore:
1.864 - case opc_lastore:
1.865 - case opc_fastore:
1.866 - case opc_dastore:
1.867 - case opc_aastore:
1.868 case opc_bastore:
1.869 case opc_castore:
1.870 case opc_sastore: {
1.871 - out.append(mapper.get(2))
1.872 - .append('[').append(mapper.get(1)).append(']')
1.873 - .append(" = ")
1.874 - .append(mapper.get(0))
1.875 - .append(';');
1.876 + out.append(mapper.getA(2)).append('[')
1.877 + .append(mapper.getI(1))
1.878 + .append(']')
1.879 + .append(" = ").append(mapper.getI(0)).append(';');
1.880 mapper.pop(3);
1.881 break;
1.882 }
1.883 + case opc_laload: {
1.884 + final Variable vidx = mapper.popI();
1.885 + final Variable varr = mapper.popA();
1.886 + out.append(mapper.pushL()).append(" = ")
1.887 + .append(varr).append('[').append(vidx).append("];");
1.888 + break;
1.889 + }
1.890 + case opc_faload: {
1.891 + final Variable vidx = mapper.popI();
1.892 + final Variable varr = mapper.popA();
1.893 + out.append(mapper.pushF()).append(" = ")
1.894 + .append(varr).append('[').append(vidx).append("];");
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 + break;
1.903 + }
1.904 + case opc_aaload: {
1.905 + final Variable vidx = mapper.popI();
1.906 + final Variable varr = mapper.popA();
1.907 + out.append(mapper.pushA()).append(" = ")
1.908 + .append(varr).append('[').append(vidx).append("];");
1.909 + break;
1.910 + }
1.911 case opc_iaload:
1.912 - case opc_laload:
1.913 - case opc_faload:
1.914 - case opc_daload:
1.915 - case opc_aaload:
1.916 case opc_baload:
1.917 case opc_caload:
1.918 case opc_saload: {
1.919 - out.append(mapper.get(1))
1.920 - .append(" = ")
1.921 - .append(mapper.get(1))
1.922 - .append('[').append(mapper.pop()).append("];");
1.923 + final Variable vidx = mapper.popI();
1.924 + final Variable varr = mapper.popA();
1.925 + out.append(mapper.pushI()).append(" = ")
1.926 + .append(varr).append('[').append(vidx).append("];");
1.927 break;
1.928 }
1.929 case opc_pop:
1.930 @@ -769,38 +1064,80 @@
1.931 mapper.pop(1);
1.932 out.append("/* pop */");
1.933 break;
1.934 - case opc_dup:
1.935 - out.append(mapper.push()).append(" = ")
1.936 - .append(mapper.get(1)).append(';');
1.937 + case opc_dup: {
1.938 + final Variable v = mapper.get(0);
1.939 + out.append(mapper.pushT(v.getType())).append(" = ")
1.940 + .append(v).append(';');
1.941 break;
1.942 - case opc_dup_x1:
1.943 + }
1.944 + case opc_dup2: {
1.945 + if (mapper.get(0).isCategory2()) {
1.946 + final Variable v = mapper.get(0);
1.947 + out.append(mapper.pushT(v.getType())).append(" = ")
1.948 + .append(v).append(';');
1.949 + } else {
1.950 + final Variable v1 = mapper.get(0);
1.951 + final Variable v2 = mapper.get(1);
1.952 + out.append("{ ");
1.953 + out.append(mapper.pushT(v2.getType())).append(" = ")
1.954 + .append(v2).append("; ");
1.955 + out.append(mapper.pushT(v1.getType())).append(" = ")
1.956 + .append(v1).append("; ");
1.957 + out.append('}');
1.958 + }
1.959 + break;
1.960 + }
1.961 + case opc_dup_x1: {
1.962 + final Variable vi1 = mapper.pop();
1.963 + final Variable vi2 = mapper.pop();
1.964 + final Variable vo3 = mapper.pushT(vi1.getType());
1.965 + final Variable vo2 = mapper.pushT(vi2.getType());
1.966 + final Variable vo1 = mapper.pushT(vi1.getType());
1.967 +
1.968 out.append("{ ");
1.969 - out.append(mapper.push()).append(" = ")
1.970 - .append(mapper.get(1)).append("; ");
1.971 - out.append(mapper.get(1)).append(" = ")
1.972 - .append(mapper.get(2)).append("; ");
1.973 - out.append(mapper.get(2)).append(" = ")
1.974 - .append(mapper.get(0)).append("; ");
1.975 + out.append(vo1).append(" = ").append(vi1).append("; ");
1.976 + out.append(vo2).append(" = ").append(vi2).append("; ");
1.977 + out.append(vo3).append(" = ").append(vo1).append("; ");
1.978 out.append('}');
1.979 break;
1.980 - case opc_dup_x2:
1.981 - out.append("{ ");
1.982 - out.append(mapper.push()).append(" = ")
1.983 - .append(mapper.get(1)).append("; ");
1.984 - out.append(mapper.get(1)).append(" = ")
1.985 - .append(mapper.get(2)).append("; ");
1.986 - out.append(mapper.get(2)).append(" = ")
1.987 - .append(mapper.get(3)).append("; ");
1.988 - out.append(mapper.get(3)).append(" = ")
1.989 - .append(mapper.get(0)).append("; ");
1.990 - out.append('}');
1.991 + }
1.992 + case opc_dup_x2: {
1.993 + if (mapper.get(1).isCategory2()) {
1.994 + final Variable vi1 = mapper.pop();
1.995 + final Variable vi2 = mapper.pop();
1.996 + final Variable vo3 = mapper.pushT(vi1.getType());
1.997 + final Variable vo2 = mapper.pushT(vi2.getType());
1.998 + final Variable vo1 = mapper.pushT(vi1.getType());
1.999 +
1.1000 + out.append("{ ");
1.1001 + out.append(vo1).append(" = ").append(vi1).append("; ");
1.1002 + out.append(vo2).append(" = ").append(vi2).append("; ");
1.1003 + out.append(vo3).append(" = ").append(vo1).append("; ");
1.1004 + out.append('}');
1.1005 + } else {
1.1006 + final Variable vi1 = mapper.pop();
1.1007 + final Variable vi2 = mapper.pop();
1.1008 + final Variable vi3 = mapper.pop();
1.1009 + final Variable vo4 = mapper.pushT(vi1.getType());
1.1010 + final Variable vo3 = mapper.pushT(vi3.getType());
1.1011 + final Variable vo2 = mapper.pushT(vi2.getType());
1.1012 + final Variable vo1 = mapper.pushT(vi1.getType());
1.1013 +
1.1014 + out.append("{ ");
1.1015 + out.append(vo1).append(" = ").append(vi1).append("; ");
1.1016 + out.append(vo2).append(" = ").append(vi2).append("; ");
1.1017 + out.append(vo3).append(" = ").append(vi3).append("; ");
1.1018 + out.append(vo4).append(" = ").append(vo1).append("; ");
1.1019 + out.append('}');
1.1020 + }
1.1021 break;
1.1022 + }
1.1023 case opc_bipush:
1.1024 - out.append(mapper.push()).append(" = ")
1.1025 + out.append(mapper.pushI()).append(" = ")
1.1026 .append(Integer.toString(byteCodes[++i])).append(';');
1.1027 break;
1.1028 case opc_sipush:
1.1029 - out.append(mapper.push()).append(" = ")
1.1030 + out.append(mapper.pushI()).append(" = ")
1.1031 .append(Integer.toString(readIntArg(byteCodes, i)))
1.1032 .append(';');
1.1033 i += 2;
1.1034 @@ -808,48 +1145,51 @@
1.1035 case opc_getfield: {
1.1036 int indx = readIntArg(byteCodes, i);
1.1037 String[] fi = jc.getFieldInfoName(indx);
1.1038 - out.append(mapper.get(0)).append(" = ")
1.1039 - .append(mapper.get(0)).append(".fld_")
1.1040 - .append(fi[1]).append(';');
1.1041 + final int type = fieldToVariableType(fi[2].charAt(0));
1.1042 + final Variable v = mapper.popA();
1.1043 + out.append(mapper.pushT(type)).append(" = ")
1.1044 + .append(v).append(".fld_").append(fi[1]).append(';');
1.1045 i += 2;
1.1046 break;
1.1047 }
1.1048 case opc_getstatic: {
1.1049 int indx = readIntArg(byteCodes, i);
1.1050 String[] fi = jc.getFieldInfoName(indx);
1.1051 - out.append(mapper.push()).append(" = ")
1.1052 + final int type = fieldToVariableType(fi[2].charAt(0));
1.1053 + out.append(mapper.pushT(type)).append(" = ")
1.1054 .append(fi[0].replace('/', '_'))
1.1055 .append('.').append(fi[1]).append(';');
1.1056 i += 2;
1.1057 addReference(fi[0]);
1.1058 break;
1.1059 }
1.1060 - case opc_putstatic: {
1.1061 - int indx = readIntArg(byteCodes, i);
1.1062 - String[] fi = jc.getFieldInfoName(indx);
1.1063 - out.append(fi[0].replace('/', '_'));
1.1064 - out.append('.').append(fi[1]).append(" = ")
1.1065 - .append(mapper.pop()).append(';');
1.1066 - i += 2;
1.1067 - addReference(fi[0]);
1.1068 - break;
1.1069 - }
1.1070 case opc_putfield: {
1.1071 int indx = readIntArg(byteCodes, i);
1.1072 String[] fi = jc.getFieldInfoName(indx);
1.1073 - out.append(mapper.get(1)).append(".fld_").append(fi[1])
1.1074 - .append(" = ")
1.1075 - .append(mapper.get(0)).append(';');
1.1076 - mapper.pop(2);
1.1077 + final int type = fieldToVariableType(fi[2].charAt(0));
1.1078 + final Variable v = mapper.popT(type);
1.1079 + out.append(mapper.popA()).append(".fld_").append(fi[1])
1.1080 + .append(" = ").append(v).append(';');
1.1081 i += 2;
1.1082 break;
1.1083 }
1.1084 + case opc_putstatic: {
1.1085 + int indx = readIntArg(byteCodes, i);
1.1086 + String[] fi = jc.getFieldInfoName(indx);
1.1087 + final int type = fieldToVariableType(fi[2].charAt(0));
1.1088 + out.append(fi[0].replace('/', '_'));
1.1089 + out.append('.').append(fi[1]).append(" = ")
1.1090 + .append(mapper.popT(type)).append(';');
1.1091 + i += 2;
1.1092 + addReference(fi[0]);
1.1093 + break;
1.1094 + }
1.1095 case opc_checkcast: {
1.1096 int indx = readIntArg(byteCodes, i);
1.1097 final String type = jc.getClassName(indx);
1.1098 if (!type.startsWith("[")) {
1.1099 // no way to check arrays right now
1.1100 - out.append("if (").append(mapper.get(0))
1.1101 + out.append("if (").append(mapper.getA(0))
1.1102 .append(".$instOf_").append(type.replace('/', '_'))
1.1103 .append(" != 1) throw {};"); // XXX proper exception
1.1104 }
1.1105 @@ -859,33 +1199,36 @@
1.1106 case opc_instanceof: {
1.1107 int indx = readIntArg(byteCodes, i);
1.1108 final String type = jc.getClassName(indx);
1.1109 - out.append(mapper.get(0)).append(" = ")
1.1110 - .append(mapper.get(0)).append(".$instOf_")
1.1111 - .append(type.replace('/', '_'))
1.1112 + final Variable v = mapper.popA();
1.1113 + out.append(mapper.pushI()).append(" = ")
1.1114 + .append(v).append(".$instOf_")
1.1115 + .append(type.replace('/', '_'))
1.1116 .append(" ? 1 : 0;");
1.1117 i += 2;
1.1118 break;
1.1119 }
1.1120 case opc_athrow: {
1.1121 + final Variable v = mapper.popA();
1.1122 + mapper.clear();
1.1123 +
1.1124 out.append("{ ");
1.1125 - out.append(mapper.bottom()).append(" = ")
1.1126 - .append(mapper.top()).append("; ");
1.1127 - out.append("throw ").append(mapper.bottom()).append("; ");
1.1128 + out.append(mapper.pushA()).append(" = ")
1.1129 + .append(v).append("; ");
1.1130 + out.append("throw ").append(v).append("; ");
1.1131 out.append('}');
1.1132
1.1133 - mapper.reset(1);
1.1134 break;
1.1135 }
1.1136
1.1137 case opc_monitorenter: {
1.1138 out.append("/* monitor enter */");
1.1139 - mapper.pop(1);
1.1140 + mapper.popA();
1.1141 break;
1.1142 }
1.1143
1.1144 case opc_monitorexit: {
1.1145 out.append("/* monitor exit */");
1.1146 - mapper.pop(1);
1.1147 + mapper.popA();
1.1148 break;
1.1149 }
1.1150
1.1151 @@ -903,22 +1246,28 @@
1.1152 out.append("\n");
1.1153 }
1.1154 out.append(" }\n");
1.1155 -
1.1156 - if (mapper.getMaxStackSize() > maxStack) {
1.1157 - throw new IllegalStateException("Incorrect stack usage");
1.1158 - }
1.1159 }
1.1160
1.1161 - private int generateIf(byte[] byteCodes, int i, final StackToVariableMapper mapper, final String test) throws IOException {
1.1162 + private int generateIf(byte[] byteCodes, int i,
1.1163 + final Variable v2, final Variable v1,
1.1164 + final String test) throws IOException {
1.1165 int indx = i + readIntArg(byteCodes, i);
1.1166 - out.append("if (").append(mapper.get(1))
1.1167 + out.append("if (").append(v1)
1.1168 .append(' ').append(test).append(' ')
1.1169 - .append(mapper.get(0)).append(") { gt = " + indx)
1.1170 + .append(v2).append(") { gt = " + indx)
1.1171 .append("; continue; }");
1.1172 - mapper.pop(2);
1.1173 return i + 2;
1.1174 }
1.1175
1.1176 + private void generateCmp(Variable v2, Variable v1, Variable vr)
1.1177 + throws IOException {
1.1178 + out.append(vr).append(" = ")
1.1179 + .append('(').append(v1).append(" == ").append(v2).append(')')
1.1180 + .append(" ? 0")
1.1181 + .append(" : ((").append(v1).append(" < ").append(v2).append(')')
1.1182 + .append(" ? -1 : 1);");
1.1183 + }
1.1184 +
1.1185 private int readIntArg(byte[] byteCodes, int offsetInstruction) {
1.1186 final int indxHi = byteCodes[offsetInstruction + 1] << 8;
1.1187 final int indxLo = byteCodes[offsetInstruction + 2];
1.1188 @@ -935,7 +1284,7 @@
1.1189 return byteCodes[offsetInstruction] & 0xff;
1.1190 }
1.1191
1.1192 - private static void countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig, StringBuilder cnt) {
1.1193 + private static void countArgs(String descriptor, char[] returnType, StringBuilder sig, StringBuilder cnt) {
1.1194 int i = 0;
1.1195 Boolean count = null;
1.1196 boolean array = false;
1.1197 @@ -971,17 +1320,19 @@
1.1198 cnt.append('0');
1.1199 }
1.1200 } else {
1.1201 - hasReturnType[0] = true;
1.1202 sig.insert(firstPos, ch);
1.1203 if (array) {
1.1204 + returnType[0] = '[';
1.1205 sig.insert(firstPos, 'A');
1.1206 + } else {
1.1207 + returnType[0] = ch;
1.1208 }
1.1209 }
1.1210 array = false;
1.1211 continue;
1.1212 case 'V':
1.1213 assert !count;
1.1214 - hasReturnType[0] = false;
1.1215 + returnType[0] = 'V';
1.1216 sig.insert(firstPos, 'V');
1.1217 continue;
1.1218 case 'L':
1.1219 @@ -999,7 +1350,7 @@
1.1220 if (array) {
1.1221 sig.insert(firstPos, 'A');
1.1222 }
1.1223 - hasReturnType[0] = true;
1.1224 + returnType[0] = 'L';
1.1225 }
1.1226 i = next + 1;
1.1227 continue;
1.1228 @@ -1022,12 +1373,11 @@
1.1229 name.append(m.getName());
1.1230 }
1.1231
1.1232 - boolean hasReturn[] = { false };
1.1233 - countArgs(findDescriptor(m.getInternalSig()), hasReturn, name, cnt);
1.1234 + countArgs(findDescriptor(m.getInternalSig()), new char[1], name, cnt);
1.1235 return name.toString();
1.1236 }
1.1237
1.1238 - private String findMethodName(String[] mi, StringBuilder cnt, boolean[] hasReturn) {
1.1239 + private String findMethodName(String[] mi, StringBuilder cnt, char[] returnType) {
1.1240 StringBuilder name = new StringBuilder();
1.1241 String descr = mi[2];//mi.getDescriptor();
1.1242 String nm= mi[1];
1.1243 @@ -1036,7 +1386,7 @@
1.1244 } else {
1.1245 name.append(nm);
1.1246 }
1.1247 - countArgs(findDescriptor(descr), hasReturn, name, cnt);
1.1248 + countArgs(findDescriptor(descr), returnType, name, cnt);
1.1249 return name.toString();
1.1250 }
1.1251
1.1252 @@ -1044,15 +1394,20 @@
1.1253 throws IOException {
1.1254 int methodIndex = readIntArg(byteCodes, i);
1.1255 String[] mi = jc.getFieldInfoName(methodIndex);
1.1256 - boolean[] hasReturn = { false };
1.1257 + char[] returnType = { 'V' };
1.1258 StringBuilder cnt = new StringBuilder();
1.1259 - String mn = findMethodName(mi, cnt, hasReturn);
1.1260 + String mn = findMethodName(mi, cnt, returnType);
1.1261
1.1262 final int numArguments = isStatic ? cnt.length() : cnt.length() + 1;
1.1263 + final Variable[] vars = new Variable[numArguments];
1.1264
1.1265 - if (hasReturn[0]) {
1.1266 - out.append((numArguments > 0) ? mapper.get(numArguments - 1)
1.1267 - : mapper.push()).append(" = ");
1.1268 + for (int j = numArguments - 1; j >= 0; --j) {
1.1269 + vars[j] = mapper.pop();
1.1270 + }
1.1271 +
1.1272 + if (returnType[0] != 'V') {
1.1273 + out.append(mapper.pushT(fieldToVariableType(returnType[0])))
1.1274 + .append(" = ");
1.1275 }
1.1276
1.1277 final String in = mi[0];
1.1278 @@ -1061,16 +1416,13 @@
1.1279 out.append(mn);
1.1280 out.append('(');
1.1281 if (numArguments > 0) {
1.1282 - out.append(mapper.get(numArguments - 1));
1.1283 - for (int j = numArguments - 2; j >= 0; --j) {
1.1284 + out.append(vars[0]);
1.1285 + for (int j = 1; j < numArguments; ++j) {
1.1286 out.append(", ");
1.1287 - out.append(mapper.get(j));
1.1288 + out.append(vars[j]);
1.1289 }
1.1290 }
1.1291 out.append(");");
1.1292 - if (numArguments > 0) {
1.1293 - mapper.pop(hasReturn[0] ? numArguments - 1 : numArguments);
1.1294 - }
1.1295 i += 2;
1.1296 addReference(in);
1.1297 return i;
1.1298 @@ -1079,26 +1431,31 @@
1.1299 throws IOException {
1.1300 int methodIndex = readIntArg(byteCodes, i);
1.1301 String[] mi = jc.getFieldInfoName(methodIndex);
1.1302 - boolean[] hasReturn = { false };
1.1303 + char[] returnType = { 'V' };
1.1304 StringBuilder cnt = new StringBuilder();
1.1305 - String mn = findMethodName(mi, cnt, hasReturn);
1.1306 + String mn = findMethodName(mi, cnt, returnType);
1.1307
1.1308 - final int numArguments = cnt.length();
1.1309 + final int numArguments = cnt.length() + 1;
1.1310 + final Variable[] vars = new Variable[numArguments];
1.1311
1.1312 - if (hasReturn[0]) {
1.1313 - out.append(mapper.get(numArguments)).append(" = ");
1.1314 + for (int j = numArguments - 1; j >= 0; --j) {
1.1315 + vars[j] = mapper.pop();
1.1316 }
1.1317
1.1318 - out.append(mapper.get(numArguments)).append('.');
1.1319 + if (returnType[0] != 'V') {
1.1320 + out.append(mapper.pushT(fieldToVariableType(returnType[0])))
1.1321 + .append(" = ");
1.1322 + }
1.1323 +
1.1324 + out.append(vars[0]).append('.');
1.1325 out.append(mn);
1.1326 out.append('(');
1.1327 - out.append(mapper.get(numArguments));
1.1328 - for (int j = numArguments - 1; j >= 0; --j) {
1.1329 + out.append(vars[0]);
1.1330 + for (int j = 1; j < numArguments; ++j) {
1.1331 out.append(", ");
1.1332 - out.append(mapper.get(j));
1.1333 + out.append(vars[j]);
1.1334 }
1.1335 out.append(");");
1.1336 - mapper.pop(hasReturn[0] ? numArguments : numArguments + 1);
1.1337 i += 2;
1.1338 return i;
1.1339 }
1.1340 @@ -1236,4 +1593,54 @@
1.1341 }
1.1342 return " = null;";
1.1343 }
1.1344 +
1.1345 + private static int constantToVariableType(final byte constantTag) {
1.1346 + switch (constantTag) {
1.1347 + case CONSTANT_INTEGER:
1.1348 + return Variable.TYPE_INT;
1.1349 + case CONSTANT_FLOAT:
1.1350 + return Variable.TYPE_FLOAT;
1.1351 + case CONSTANT_LONG:
1.1352 + return Variable.TYPE_LONG;
1.1353 + case CONSTANT_DOUBLE:
1.1354 + return Variable.TYPE_DOUBLE;
1.1355 +
1.1356 + case CONSTANT_CLASS:
1.1357 + case CONSTANT_UTF8:
1.1358 + case CONSTANT_UNICODE:
1.1359 + case CONSTANT_STRING:
1.1360 + return Variable.TYPE_REF;
1.1361 +
1.1362 + case CONSTANT_FIELD:
1.1363 + case CONSTANT_METHOD:
1.1364 + case CONSTANT_INTERFACEMETHOD:
1.1365 + case CONSTANT_NAMEANDTYPE:
1.1366 + /* unclear how to handle for now */
1.1367 + default:
1.1368 + throw new IllegalStateException("Unhandled constant tag");
1.1369 + }
1.1370 + }
1.1371 +
1.1372 + private static int fieldToVariableType(final char fieldType) {
1.1373 + switch (fieldType) {
1.1374 + case 'B':
1.1375 + case 'C':
1.1376 + case 'S':
1.1377 + case 'Z':
1.1378 + case 'I':
1.1379 + return Variable.TYPE_INT;
1.1380 + case 'J':
1.1381 + return Variable.TYPE_LONG;
1.1382 + case 'F':
1.1383 + return Variable.TYPE_FLOAT;
1.1384 + case 'D':
1.1385 + return Variable.TYPE_DOUBLE;
1.1386 + case 'L':
1.1387 + case '[':
1.1388 + return Variable.TYPE_REF;
1.1389 +
1.1390 + default:
1.1391 + throw new IllegalStateException("Unhandled field type");
1.1392 + }
1.1393 + }
1.1394 }