Reduced stack seems to be stable enough to be merged into default branch
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 19 Feb 2014 08:10:04 +0100
changeset 14784ce73c83c775
parent 1460 ef506621d1ee
parent 1477 b012365f8fb7
child 1480 797da74ddde1
Reduced stack seems to be stable enough to be merged into default branch
     1.1 --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Sun Feb 16 20:06:03 2014 +0100
     1.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Wed Feb 19 08:10:04 2014 +0100
     1.3 @@ -250,6 +250,17 @@
     1.4          }
     1.5      }
     1.6      
     1.7 +    @Compare public int callAbst() throws Exception {
     1.8 +        class Impl extends Abst {
     1.9 +            @Override
    1.10 +            public int abst() {
    1.11 +                return 10;
    1.12 +            }
    1.13 +        }
    1.14 +        Abst impl = new Impl();
    1.15 +        return (int) Abst.class.getMethod("abst").invoke(impl);
    1.16 +    }
    1.17 +    
    1.18      @Compare public String componentGetNameForObjectArray() {
    1.19          return (new Object[3]).getClass().getComponentType().getName();
    1.20      }
    1.21 @@ -296,4 +307,7 @@
    1.22          return VMTest.create(ReflectionTest.class);
    1.23      }
    1.24      
    1.25 +    public static abstract class Abst {
    1.26 +        public abstract int abst();
    1.27 +    }
    1.28  }
     2.1 --- a/rt/emul/mini/src/main/java/java/lang/Object.java	Sun Feb 16 20:06:03 2014 +0100
     2.2 +++ b/rt/emul/mini/src/main/java/java/lang/Object.java	Wed Feb 19 08:10:04 2014 +0100
     2.3 @@ -43,7 +43,7 @@
     2.4  
     2.5      private static void registerNatives() {
     2.6          boolean assertsOn = false;
     2.7 -        assert assertsOn = false;
     2.8 + //       assert assertsOn = true;
     2.9          if (assertsOn) try {
    2.10              Array.get(null, 0);
    2.11          } catch (Throwable ex) {
     3.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Sun Feb 16 20:06:03 2014 +0100
     3.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Wed Feb 19 08:10:04 2014 +0100
     3.3 @@ -528,15 +528,17 @@
     3.4      }
     3.5      
     3.6      @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
     3.7 -          "var p;\n"
     3.8 +          "var p; var cll;\n"
     3.9          + "if (st) {\n"
    3.10 +        + "  cll = self[method._name() + '__' + method._sig()];\n"
    3.11          + "  p = new Array(1);\n"
    3.12          + "  p[0] = self;\n"
    3.13          + "  p = p.concat(args);\n"
    3.14          + "} else {\n"
    3.15          + "  p = args;\n"
    3.16 +        + "  cll = method._data();"
    3.17          + "}\n"
    3.18 -        + "return method._data().apply(self, p);\n"
    3.19 +        + "return cll.apply(self, p);\n"
    3.20      )
    3.21      private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
    3.22      
     4.1 --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Sun Feb 16 20:06:03 2014 +0100
     4.2 +++ b/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Wed Feb 19 08:10:04 2014 +0100
     4.3 @@ -51,12 +51,12 @@
     4.4      }
     4.5  
     4.6      @JavaScriptBody(args = { "arr", "expectedSize" }, body = 
     4.7 -        "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
     4.8 +        "while (expectedSize > arr.length) { arr.push(0); }; return arr;"
     4.9      )
    4.10      public static native byte[] expandArray(byte[] arr, int expectedSize);
    4.11  
    4.12      @JavaScriptBody(args = { "arr", "expectedSize" }, body = 
    4.13 -        "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
    4.14 +        "while (expectedSize > arr.length) { arr.push(0); }; return arr;"
    4.15      )
    4.16      public static native char[] expandArray(char[] arr, int expectedSize);
    4.17  
     5.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Sun Feb 16 20:06:03 2014 +0100
     5.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Wed Feb 19 08:10:04 2014 +0100
     5.3 @@ -224,6 +224,14 @@
     5.4              return hi.next32(low);
     5.5          }
     5.6      };
     5.7 +    
     5.8 +    numberPrototype.compare = function(x) {
     5.9 +        if (this == x) {
    5.10 +            return 0;
    5.11 +        } else {
    5.12 +            return (this < x) ? -1 : 1;
    5.13 +        }
    5.14 +    };
    5.15  
    5.16      numberPrototype.compare64 = function(x) {
    5.17          if (this.high32() === x.high32()) {
     6.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java	Sun Feb 16 20:06:03 2014 +0100
     6.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java	Wed Feb 19 08:10:04 2014 +0100
     6.3 @@ -39,37 +39,6 @@
     6.4  final class ByteCodeParser {
     6.5      private ByteCodeParser() {
     6.6      }
     6.7 -    /* Signature Characters */
     6.8 -    public static final char   SIGC_VOID                  = 'V';
     6.9 -    public static final String SIG_VOID                   = "V";
    6.10 -    public static final char   SIGC_BOOLEAN               = 'Z';
    6.11 -    public static final String SIG_BOOLEAN                = "Z";
    6.12 -    public static final char   SIGC_BYTE                  = 'B';
    6.13 -    public static final String SIG_BYTE                   = "B";
    6.14 -    public static final char   SIGC_CHAR                  = 'C';
    6.15 -    public static final String SIG_CHAR                   = "C";
    6.16 -    public static final char   SIGC_SHORT                 = 'S';
    6.17 -    public static final String SIG_SHORT                  = "S";
    6.18 -    public static final char   SIGC_INT                   = 'I';
    6.19 -    public static final String SIG_INT                    = "I";
    6.20 -    public static final char   SIGC_LONG                  = 'J';
    6.21 -    public static final String SIG_LONG                   = "J";
    6.22 -    public static final char   SIGC_FLOAT                 = 'F';
    6.23 -    public static final String SIG_FLOAT                  = "F";
    6.24 -    public static final char   SIGC_DOUBLE                = 'D';
    6.25 -    public static final String SIG_DOUBLE                 = "D";
    6.26 -    public static final char   SIGC_ARRAY                 = '[';
    6.27 -    public static final String SIG_ARRAY                  = "[";
    6.28 -    public static final char   SIGC_CLASS                 = 'L';
    6.29 -    public static final String SIG_CLASS                  = "L";
    6.30 -    public static final char   SIGC_METHOD                = '(';
    6.31 -    public static final String SIG_METHOD                 = "(";
    6.32 -    public static final char   SIGC_ENDCLASS              = ';';
    6.33 -    public static final String SIG_ENDCLASS               = ";";
    6.34 -    public static final char   SIGC_ENDMETHOD             = ')';
    6.35 -    public static final String SIG_ENDMETHOD              = ")";
    6.36 -    public static final char   SIGC_PACKAGE               = '/';
    6.37 -    public static final String SIG_PACKAGE                = "/";
    6.38  
    6.39      /* Class File Constants */
    6.40      public static final int JAVA_MAGIC                   = 0xcafebabe;
    6.41 @@ -107,17 +76,6 @@
    6.42      public static final int ACC_EXPLICIT                 = 0x00001000;
    6.43      public static final int ACC_SYNTHETIC                = 0x00010000; // actually, this is an attribute
    6.44  
    6.45 -    /* Type codes */
    6.46 -    public static final int T_CLASS                      = 0x00000002;
    6.47 -    public static final int T_BOOLEAN                    = 0x00000004;
    6.48 -    public static final int T_CHAR                       = 0x00000005;
    6.49 -    public static final int T_FLOAT                      = 0x00000006;
    6.50 -    public static final int T_DOUBLE                     = 0x00000007;
    6.51 -    public static final int T_BYTE                       = 0x00000008;
    6.52 -    public static final int T_SHORT                      = 0x00000009;
    6.53 -    public static final int T_INT                        = 0x0000000a;
    6.54 -    public static final int T_LONG                       = 0x0000000b;
    6.55 -
    6.56      /* Type codes for StackMap attribute */
    6.57      public static final int ITEM_Bogus      =0; // an unknown or uninitialized value
    6.58      public static final int ITEM_Integer    =1; // a 32-bit integer
    6.59 @@ -358,7 +316,7 @@
    6.60      public static final int opc_nonpriv                  = 254;
    6.61      public static final int opc_priv                     = 255;
    6.62  
    6.63 -        /* Wide instructions */
    6.64 +        /* Wide instructions *
    6.65      public static final int opc_iload_w         = (opc_wide<<8)|opc_iload;
    6.66      public static final int opc_lload_w         = (opc_wide<<8)|opc_lload;
    6.67      public static final int opc_fload_w         = (opc_wide<<8)|opc_fload;
    6.68 @@ -371,762 +329,7 @@
    6.69      public static final int opc_astore_w        = (opc_wide<<8)|opc_astore;
    6.70      public static final int opc_ret_w           = (opc_wide<<8)|opc_ret;
    6.71      public static final int opc_iinc_w          = (opc_wide<<8)|opc_iinc;
    6.72 -
    6.73 -    /* Opcode Names */
    6.74 -  public static final String opcNamesTab[] = {
    6.75 -        "nop",
    6.76 -        "aconst_null",
    6.77 -        "iconst_m1",
    6.78 -        "iconst_0",
    6.79 -        "iconst_1",
    6.80 -        "iconst_2",
    6.81 -        "iconst_3",
    6.82 -        "iconst_4",
    6.83 -        "iconst_5",
    6.84 -        "lconst_0",
    6.85 -        "lconst_1",
    6.86 -        "fconst_0",
    6.87 -        "fconst_1",
    6.88 -        "fconst_2",
    6.89 -        "dconst_0",
    6.90 -        "dconst_1",
    6.91 -        "bipush",
    6.92 -        "sipush",
    6.93 -        "ldc",
    6.94 -        "ldc_w",
    6.95 -        "ldc2_w",
    6.96 -        "iload",
    6.97 -        "lload",
    6.98 -        "fload",
    6.99 -        "dload",
   6.100 -        "aload",
   6.101 -        "iload_0",
   6.102 -        "iload_1",
   6.103 -        "iload_2",
   6.104 -        "iload_3",
   6.105 -        "lload_0",
   6.106 -        "lload_1",
   6.107 -        "lload_2",
   6.108 -        "lload_3",
   6.109 -        "fload_0",
   6.110 -        "fload_1",
   6.111 -        "fload_2",
   6.112 -        "fload_3",
   6.113 -        "dload_0",
   6.114 -        "dload_1",
   6.115 -        "dload_2",
   6.116 -        "dload_3",
   6.117 -        "aload_0",
   6.118 -        "aload_1",
   6.119 -        "aload_2",
   6.120 -        "aload_3",
   6.121 -        "iaload",
   6.122 -        "laload",
   6.123 -        "faload",
   6.124 -        "daload",
   6.125 -        "aaload",
   6.126 -        "baload",
   6.127 -        "caload",
   6.128 -        "saload",
   6.129 -        "istore",
   6.130 -        "lstore",
   6.131 -        "fstore",
   6.132 -        "dstore",
   6.133 -        "astore",
   6.134 -        "istore_0",
   6.135 -        "istore_1",
   6.136 -        "istore_2",
   6.137 -        "istore_3",
   6.138 -        "lstore_0",
   6.139 -        "lstore_1",
   6.140 -        "lstore_2",
   6.141 -        "lstore_3",
   6.142 -        "fstore_0",
   6.143 -        "fstore_1",
   6.144 -        "fstore_2",
   6.145 -        "fstore_3",
   6.146 -        "dstore_0",
   6.147 -        "dstore_1",
   6.148 -        "dstore_2",
   6.149 -        "dstore_3",
   6.150 -        "astore_0",
   6.151 -        "astore_1",
   6.152 -        "astore_2",
   6.153 -        "astore_3",
   6.154 -        "iastore",
   6.155 -        "lastore",
   6.156 -        "fastore",
   6.157 -        "dastore",
   6.158 -        "aastore",
   6.159 -        "bastore",
   6.160 -        "castore",
   6.161 -        "sastore",
   6.162 -        "pop",
   6.163 -        "pop2",
   6.164 -        "dup",
   6.165 -        "dup_x1",
   6.166 -        "dup_x2",
   6.167 -        "dup2",
   6.168 -        "dup2_x1",
   6.169 -        "dup2_x2",
   6.170 -        "swap",
   6.171 -        "iadd",
   6.172 -        "ladd",
   6.173 -        "fadd",
   6.174 -        "dadd",
   6.175 -        "isub",
   6.176 -        "lsub",
   6.177 -        "fsub",
   6.178 -        "dsub",
   6.179 -        "imul",
   6.180 -        "lmul",
   6.181 -        "fmul",
   6.182 -        "dmul",
   6.183 -        "idiv",
   6.184 -        "ldiv",
   6.185 -        "fdiv",
   6.186 -        "ddiv",
   6.187 -        "irem",
   6.188 -        "lrem",
   6.189 -        "frem",
   6.190 -        "drem",
   6.191 -        "ineg",
   6.192 -        "lneg",
   6.193 -        "fneg",
   6.194 -        "dneg",
   6.195 -        "ishl",
   6.196 -        "lshl",
   6.197 -        "ishr",
   6.198 -        "lshr",
   6.199 -        "iushr",
   6.200 -        "lushr",
   6.201 -        "iand",
   6.202 -        "land",
   6.203 -        "ior",
   6.204 -        "lor",
   6.205 -        "ixor",
   6.206 -        "lxor",
   6.207 -        "iinc",
   6.208 -        "i2l",
   6.209 -        "i2f",
   6.210 -        "i2d",
   6.211 -        "l2i",
   6.212 -        "l2f",
   6.213 -        "l2d",
   6.214 -        "f2i",
   6.215 -        "f2l",
   6.216 -        "f2d",
   6.217 -        "d2i",
   6.218 -        "d2l",
   6.219 -        "d2f",
   6.220 -        "i2b",
   6.221 -        "i2c",
   6.222 -        "i2s",
   6.223 -        "lcmp",
   6.224 -        "fcmpl",
   6.225 -        "fcmpg",
   6.226 -        "dcmpl",
   6.227 -        "dcmpg",
   6.228 -        "ifeq",
   6.229 -        "ifne",
   6.230 -        "iflt",
   6.231 -        "ifge",
   6.232 -        "ifgt",
   6.233 -        "ifle",
   6.234 -        "if_icmpeq",
   6.235 -        "if_icmpne",
   6.236 -        "if_icmplt",
   6.237 -        "if_icmpge",
   6.238 -        "if_icmpgt",
   6.239 -        "if_icmple",
   6.240 -        "if_acmpeq",
   6.241 -        "if_acmpne",
   6.242 -        "goto",
   6.243 -        "jsr",
   6.244 -        "ret",
   6.245 -        "tableswitch",
   6.246 -        "lookupswitch",
   6.247 -        "ireturn",
   6.248 -        "lreturn",
   6.249 -        "freturn",
   6.250 -        "dreturn",
   6.251 -        "areturn",
   6.252 -        "return",
   6.253 -        "getstatic",
   6.254 -        "putstatic",
   6.255 -        "getfield",
   6.256 -        "putfield",
   6.257 -        "invokevirtual",
   6.258 -        "invokespecial", //     was "invokenonvirtual",
   6.259 -        "invokestatic",
   6.260 -        "invokeinterface",
   6.261 -        "bytecode 186", //"xxxunusedxxx",
   6.262 -        "new",
   6.263 -        "newarray",
   6.264 -        "anewarray",
   6.265 -        "arraylength",
   6.266 -        "athrow",
   6.267 -        "checkcast",
   6.268 -        "instanceof",
   6.269 -        "monitorenter",
   6.270 -        "monitorexit",
   6.271 -         null, // "wide",
   6.272 -        "multianewarray",
   6.273 -        "ifnull",
   6.274 -        "ifnonnull",
   6.275 -        "goto_w",
   6.276 -        "jsr_w",
   6.277 -        "bytecode 202", // "breakpoint",
   6.278 -        "bytecode",
   6.279 -        "try",
   6.280 -        "endtry",
   6.281 -        "catch",
   6.282 -        "var",
   6.283 -        "endvar",
   6.284 -        "locals_map",
   6.285 -        "stack_map"
   6.286 -  };
   6.287 -
   6.288 -    /* Opcode Lengths */
   6.289 -  public static final int opcLengthsTab[] = {
   6.290 -        1,
   6.291 -        1,
   6.292 -        1,
   6.293 -        1,
   6.294 -        1,
   6.295 -        1,
   6.296 -        1,
   6.297 -        1,
   6.298 -        1,
   6.299 -        1,
   6.300 -        1,
   6.301 -        1,
   6.302 -        1,
   6.303 -        1,
   6.304 -        1,
   6.305 -        1,
   6.306 -        2,
   6.307 -        3,
   6.308 -        2,
   6.309 -        3,
   6.310 -        3,
   6.311 -        2,
   6.312 -        2,
   6.313 -        2,
   6.314 -        2,
   6.315 -        2,
   6.316 -        1,
   6.317 -        1,
   6.318 -        1,
   6.319 -        1,
   6.320 -        1,
   6.321 -        1,
   6.322 -        1,
   6.323 -        1,
   6.324 -        1,
   6.325 -        1,
   6.326 -        1,
   6.327 -        1,
   6.328 -        1,
   6.329 -        1,
   6.330 -        1,
   6.331 -        1,
   6.332 -        1,
   6.333 -        1,
   6.334 -        1,
   6.335 -        1,
   6.336 -        1,
   6.337 -        1,
   6.338 -        1,
   6.339 -        1,
   6.340 -        1,
   6.341 -        1,
   6.342 -        1,
   6.343 -        1,
   6.344 -        2,
   6.345 -        2,
   6.346 -        2,
   6.347 -        2,
   6.348 -        2,
   6.349 -        1,
   6.350 -        1,
   6.351 -        1,
   6.352 -        1,
   6.353 -        1,
   6.354 -        1,
   6.355 -        1,
   6.356 -        1,
   6.357 -        1,
   6.358 -        1,
   6.359 -        1,
   6.360 -        1,
   6.361 -        1,
   6.362 -        1,
   6.363 -        1,
   6.364 -        1,
   6.365 -        1,
   6.366 -        1,
   6.367 -        1,
   6.368 -        1,
   6.369 -        1,
   6.370 -        1,
   6.371 -        1,
   6.372 -        1,
   6.373 -        1,
   6.374 -        1,
   6.375 -        1,
   6.376 -        1,
   6.377 -        1,
   6.378 -        1,
   6.379 -        1,
   6.380 -        1,
   6.381 -        1,
   6.382 -        1,
   6.383 -        1,
   6.384 -        1,
   6.385 -        1,
   6.386 -        1,
   6.387 -        1,
   6.388 -        1,
   6.389 -        1,
   6.390 -        1,
   6.391 -        1,
   6.392 -        1,
   6.393 -        1,
   6.394 -        1,
   6.395 -        1,
   6.396 -        1,
   6.397 -        1,
   6.398 -        1,
   6.399 -        1,
   6.400 -        1,
   6.401 -        1,
   6.402 -        1,
   6.403 -        1,
   6.404 -        1,
   6.405 -        1,
   6.406 -        1,
   6.407 -        1,
   6.408 -        1,
   6.409 -        1,
   6.410 -        1,
   6.411 -        1,
   6.412 -        1,
   6.413 -        1,
   6.414 -        1,
   6.415 -        1,
   6.416 -        1,
   6.417 -        1,
   6.418 -        1,
   6.419 -        1,
   6.420 -        1,
   6.421 -        1,
   6.422 -        3,
   6.423 -        1,
   6.424 -        1,
   6.425 -        1,
   6.426 -        1,
   6.427 -        1,
   6.428 -        1,
   6.429 -        1,
   6.430 -        1,
   6.431 -        1,
   6.432 -        1,
   6.433 -        1,
   6.434 -        1,
   6.435 -        1,
   6.436 -        1,
   6.437 -        1,
   6.438 -        1,
   6.439 -        1,
   6.440 -        1,
   6.441 -        1,
   6.442 -        1,
   6.443 -        3,
   6.444 -        3,
   6.445 -        3,
   6.446 -        3,
   6.447 -        3,
   6.448 -        3,
   6.449 -        3,
   6.450 -        3,
   6.451 -        3,
   6.452 -        3,
   6.453 -        3,
   6.454 -        3,
   6.455 -        3,
   6.456 -        3,
   6.457 -        3,
   6.458 -        3,
   6.459 -        2,
   6.460 -        99,
   6.461 -        99,
   6.462 -        1,
   6.463 -        1,
   6.464 -        1,
   6.465 -        1,
   6.466 -        1,
   6.467 -        1,
   6.468 -        3,
   6.469 -        3,
   6.470 -        3,
   6.471 -        3,
   6.472 -        3,
   6.473 -        3,
   6.474 -        3,
   6.475 -        5,
   6.476 -        0,
   6.477 -        3,
   6.478 -        2,
   6.479 -        3,
   6.480 -        1,
   6.481 -        1,
   6.482 -        3,
   6.483 -        3,
   6.484 -        1,
   6.485 -        1,
   6.486 -        0, // wide
   6.487 -        4,
   6.488 -        3,
   6.489 -        3,
   6.490 -        5,
   6.491 -        5,
   6.492 -        1,
   6.493 -        1, 0, 0, 0, 0, 0 // pseudo
   6.494 -  };
   6.495 -
   6.496 -     /**
   6.497 -     * End of input
   6.498 -     */
   6.499 -    public static final int EOF = -1;
   6.500 -
   6.501 -   /*
   6.502 -     * Flags
   6.503 -     */
   6.504 -    public static final int F_VERBOSE           = 1 << 0;
   6.505 -    public static final int F_DUMP              = 1 << 1;
   6.506 -    public static final int F_WARNINGS          = 1 << 2;
   6.507 -    public static final int F_DEBUG             = 1 << 3;
   6.508 -    public static final int F_OPTIMIZE          = 1 << 4;
   6.509 -    public static final int F_DEPENDENCIES      = 1 << 5;
   6.510 -
   6.511 -    /*
   6.512 -     * Type codes
   6.513 -     */
   6.514 -    public static final int TC_BOOLEAN   = 0;
   6.515 -    public static final int TC_BYTE      = 1;
   6.516 -    public static final int TC_CHAR      = 2;
   6.517 -    public static final int TC_SHORT     = 3;
   6.518 -    public static final int TC_INT       = 4;
   6.519 -    public static final int TC_LONG      = 5;
   6.520 -    public static final int TC_FLOAT     = 6;
   6.521 -    public static final int TC_DOUBLE    = 7;
   6.522 -    public static final int TC_NULL      = 8;
   6.523 -    public static final int TC_ARRAY     = 9;
   6.524 -    public static final int TC_CLASS     = 10;
   6.525 -    public static final int TC_VOID      = 11;
   6.526 -    public static final int TC_METHOD    = 12;
   6.527 -    public static final int TC_ERROR     = 13;
   6.528 -
   6.529 -    /*
   6.530 -     * Type Masks
   6.531 -     */
   6.532 -    public static final int TM_NULL      = 1 << TC_NULL;
   6.533 -    public static final int TM_VOID      = 1 << TC_VOID;
   6.534 -    public static final int TM_BOOLEAN   = 1 << TC_BOOLEAN;
   6.535 -    public static final int TM_BYTE      = 1 << TC_BYTE;
   6.536 -    public static final int TM_CHAR      = 1 << TC_CHAR;
   6.537 -    public static final int TM_SHORT     = 1 << TC_SHORT;
   6.538 -    public static final int TM_INT       = 1 << TC_INT;
   6.539 -    public static final int TM_LONG      = 1 << TC_LONG;
   6.540 -    public static final int TM_FLOAT     = 1 << TC_FLOAT;
   6.541 -    public static final int TM_DOUBLE    = 1 << TC_DOUBLE;
   6.542 -    public static final int TM_ARRAY     = 1 << TC_ARRAY;
   6.543 -    public static final int TM_CLASS     = 1 << TC_CLASS;
   6.544 -    public static final int TM_METHOD    = 1 << TC_METHOD;
   6.545 -    public static final int TM_ERROR     = 1 << TC_ERROR;
   6.546 -
   6.547 -    public static final int TM_INT32     = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
   6.548 -    public static final int TM_NUM32     = TM_INT32 | TM_FLOAT;
   6.549 -    public static final int TM_NUM64     = TM_LONG | TM_DOUBLE;
   6.550 -    public static final int TM_INTEGER   = TM_INT32 | TM_LONG;
   6.551 -    public static final int TM_REAL      = TM_FLOAT | TM_DOUBLE;
   6.552 -    public static final int TM_NUMBER    = TM_INTEGER | TM_REAL;
   6.553 -    public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
   6.554 -
   6.555 -    /*
   6.556 -     * Class status
   6.557 -     */
   6.558 -    public static final int CS_UNDEFINED        = 0;
   6.559 -    public static final int CS_UNDECIDED        = 1;
   6.560 -    public static final int CS_BINARY           = 2;
   6.561 -    public static final int CS_SOURCE           = 3;
   6.562 -    public static final int CS_PARSED           = 4;
   6.563 -    public static final int CS_COMPILED         = 5;
   6.564 -    public static final int CS_NOTFOUND         = 6;
   6.565 -
   6.566 -    /*
   6.567 -     * Attributes
   6.568 -     */
   6.569 -    public static final int ATT_ALL             = -1;
   6.570 -    public static final int ATT_CODE            = 1;
   6.571 -
   6.572 -    /*
   6.573 -     * Number of bits used in file offsets
   6.574 -     */
   6.575 -    public static final int OFFSETBITS          = 19;
   6.576 -    public static final int MAXFILESIZE         = (1 << OFFSETBITS) - 1;
   6.577 -    public static final int MAXLINENUMBER       = (1 << (32 - OFFSETBITS)) - 1;
   6.578 -
   6.579 -    /*
   6.580 -     * Operators
   6.581 -     */
   6.582 -    public final int COMMA              = 0;
   6.583 -    public final int ASSIGN             = 1;
   6.584 -
   6.585 -    public final int ASGMUL             = 2;
   6.586 -    public final int ASGDIV             = 3;
   6.587 -    public final int ASGREM             = 4;
   6.588 -    public final int ASGADD             = 5;
   6.589 -    public final int ASGSUB             = 6;
   6.590 -    public final int ASGLSHIFT          = 7;
   6.591 -    public final int ASGRSHIFT          = 8;
   6.592 -    public final int ASGURSHIFT         = 9;
   6.593 -    public final int ASGBITAND          = 10;
   6.594 -    public final int ASGBITOR           = 11;
   6.595 -    public final int ASGBITXOR          = 12;
   6.596 -
   6.597 -    public final int COND               = 13;
   6.598 -    public final int OR                 = 14;
   6.599 -    public final int AND                = 15;
   6.600 -    public final int BITOR              = 16;
   6.601 -    public final int BITXOR             = 17;
   6.602 -    public final int BITAND             = 18;
   6.603 -    public final int NE                 = 19;
   6.604 -    public final int EQ                 = 20;
   6.605 -    public final int GE                 = 21;
   6.606 -    public final int GT                 = 22;
   6.607 -    public final int LE                 = 23;
   6.608 -    public final int LT                 = 24;
   6.609 -    public final int INSTANCEOF         = 25;
   6.610 -    public final int LSHIFT             = 26;
   6.611 -    public final int RSHIFT             = 27;
   6.612 -    public final int URSHIFT            = 28;
   6.613 -    public final int ADD                = 29;
   6.614 -    public final int SUB                = 30;
   6.615 -    public final int DIV                = 31;
   6.616 -    public final int REM                = 32;
   6.617 -    public final int MUL                = 33;
   6.618 -    public final int CAST               = 34;           // (x)y
   6.619 -    public final int POS                = 35;           // +x
   6.620 -    public final int NEG                = 36;           // -x
   6.621 -    public final int NOT                = 37;
   6.622 -    public final int BITNOT             = 38;
   6.623 -    public final int PREINC             = 39;           // ++x
   6.624 -    public final int PREDEC             = 40;           // --x
   6.625 -    public final int NEWARRAY           = 41;
   6.626 -    public final int NEWINSTANCE        = 42;
   6.627 -    public final int NEWFROMNAME        = 43;
   6.628 -    public final int POSTINC            = 44;           // x++
   6.629 -    public final int POSTDEC            = 45;           // x--
   6.630 -    public final int FIELD              = 46;
   6.631 -    public final int METHOD             = 47;           // x(y)
   6.632 -    public final int ARRAYACCESS        = 48;           // x[y]
   6.633 -    public final int NEW                = 49;
   6.634 -    public final int INC                = 50;
   6.635 -    public final int DEC                = 51;
   6.636 -
   6.637 -    public final int CONVERT            = 55;           // implicit conversion
   6.638 -    public final int EXPR               = 56;           // (x)
   6.639 -    public final int ARRAY              = 57;           // {x, y, ...}
   6.640 -    public final int GOTO               = 58;
   6.641 -
   6.642 -    /*
   6.643 -     * Value tokens
   6.644 -     */
   6.645 -    public final int IDENT              = 60;
   6.646 -    public final int BOOLEANVAL         = 61;
   6.647 -    public final int BYTEVAL            = 62;
   6.648 -    public final int CHARVAL            = 63;
   6.649 -    public final int SHORTVAL           = 64;
   6.650 -    public final int INTVAL                     = 65;
   6.651 -    public final int LONGVAL            = 66;
   6.652 -    public final int FLOATVAL           = 67;
   6.653 -    public final int DOUBLEVAL          = 68;
   6.654 -    public final int STRINGVAL          = 69;
   6.655 -
   6.656 -    /*
   6.657 -     * Type keywords
   6.658 -     */
   6.659 -    public final int BYTE               = 70;
   6.660 -    public final int CHAR               = 71;
   6.661 -    public final int SHORT              = 72;
   6.662 -    public final int INT                = 73;
   6.663 -    public final int LONG               = 74;
   6.664 -    public final int FLOAT              = 75;
   6.665 -    public final int DOUBLE             = 76;
   6.666 -    public final int VOID               = 77;
   6.667 -    public final int BOOLEAN            = 78;
   6.668 -
   6.669 -    /*
   6.670 -     * Expression keywords
   6.671 -     */
   6.672 -    public final int TRUE               = 80;
   6.673 -    public final int FALSE              = 81;
   6.674 -    public final int THIS               = 82;
   6.675 -    public final int SUPER              = 83;
   6.676 -    public final int NULL               = 84;
   6.677 -
   6.678 -    /*
   6.679 -     * Statement keywords
   6.680 -     */
   6.681 -    public final int IF                 = 90;
   6.682 -    public final int ELSE               = 91;
   6.683 -    public final int FOR                = 92;
   6.684 -    public final int WHILE              = 93;
   6.685 -    public final int DO                 = 94;
   6.686 -    public final int SWITCH             = 95;
   6.687 -    public final int CASE               = 96;
   6.688 -    public final int DEFAULT            = 97;
   6.689 -    public final int BREAK              = 98;
   6.690 -    public final int CONTINUE           = 99;
   6.691 -    public final int RETURN             = 100;
   6.692 -    public final int TRY                = 101;
   6.693 -    public final int CATCH              = 102;
   6.694 -    public final int FINALLY            = 103;
   6.695 -    public final int THROW              = 104;
   6.696 -    public final int STAT               = 105;
   6.697 -    public final int EXPRESSION         = 106;
   6.698 -    public final int DECLARATION        = 107;
   6.699 -    public final int VARDECLARATION     = 108;
   6.700 -
   6.701 -    /*
   6.702 -     * Declaration keywords
   6.703 -     */
   6.704 -    public final int IMPORT             = 110;
   6.705 -    public final int CLASS              = 111;
   6.706 -    public final int EXTENDS            = 112;
   6.707 -    public final int IMPLEMENTS         = 113;
   6.708 -    public final int INTERFACE          = 114;
   6.709 -    public final int PACKAGE            = 115;
   6.710 -
   6.711 -    /*
   6.712 -     * Modifier keywords
   6.713 -     */
   6.714 -    public final int PRIVATE    = 120;
   6.715 -    public final int PUBLIC             = 121;
   6.716 -    public final int PROTECTED  = 122;
   6.717 -    public final int CONST              = 123;
   6.718 -    public final int STATIC             = 124;
   6.719 -    public final int TRANSIENT          = 125;
   6.720 -    public final int SYNCHRONIZED       = 126;
   6.721 -    public final int NATIVE             = 127;
   6.722 -    public final int FINAL              = 128;
   6.723 -    public final int VOLATILE   = 129;
   6.724 -    public final int ABSTRACT   = 130;
   6.725 -    public final int STRICT             = 165;
   6.726 -
   6.727 -    /*
   6.728 -     * Punctuation
   6.729 -     */
   6.730 -    public final int SEMICOLON  = 135;
   6.731 -    public final int COLON              = 136;
   6.732 -    public final int QUESTIONMARK       = 137;
   6.733 -    public final int LBRACE             = 138;
   6.734 -    public final int RBRACE             = 139;
   6.735 -    public final int LPAREN             = 140;
   6.736 -    public final int RPAREN             = 141;
   6.737 -    public final int LSQBRACKET = 142;
   6.738 -    public final int RSQBRACKET = 143;
   6.739 -    public final int THROWS     = 144;
   6.740 -
   6.741 -    /*
   6.742 -     * Special tokens
   6.743 -     */
   6.744 -    public final int ERROR              = 145;          // an error
   6.745 -    public final int COMMENT    = 146;          // not used anymore.
   6.746 -    public final int TYPE               = 147;
   6.747 -    public final int LENGTH             = 148;
   6.748 -    public final int INLINERETURN       = 149;
   6.749 -    public final int INLINEMETHOD       = 150;
   6.750 -    public final int INLINENEWINSTANCE  = 151;
   6.751 -
   6.752 -    /*
   6.753 -     * Added for jasm
   6.754 -     */
   6.755 -        public final int METHODREF      = 152;
   6.756 -        public final int FIELDREF       = 153;
   6.757 -    public final int STACK              = 154;
   6.758 -    public final int LOCAL              = 155;
   6.759 -    public final int CPINDEX    = 156;
   6.760 -    public final int CPNAME             = 157;
   6.761 -    public final int SIGN               = 158;
   6.762 -    public final int BITS               = 159;
   6.763 -    public final int INF                = 160;
   6.764 -    public final int NAN                = 161;
   6.765 -    public final int INNERCLASS = 162;
   6.766 -    public final int OF         = 163;
   6.767 -    public final int SYNTHETIC          = 164;
   6.768 -// last used=165;
   6.769 -
   6.770 -   /*
   6.771 -     * Operator precedence
   6.772 -     */
   6.773 -    public static final int opPrecedence[] = {
   6.774 -        10,     11,     11,     11,     11,     11,     11,     11,     11,     11,
   6.775 -        11,     11,     11,     12,     13,     14,     15,     16,     17,     18,
   6.776 -        18,     19,     19,     19,     19,     19,     20,     20,     20,     21,
   6.777 -        21,     22,     22,     22,     23,     24,     24,     24,     24,     24,
   6.778 -        24,     25,     25,     26,     26,     26,     26,     26,     26
   6.779 -    };
   6.780 -
   6.781 -    /*
   6.782 -     * Operator names
   6.783 -     */
   6.784 -    public static final String opNames[] = {
   6.785 -        ",",            "=",            "*=",           "/=",           "%=",
   6.786 -        "+=",           "-=",           "<<=",          ">>=",          "<<<=",
   6.787 -        "&=",           "|=",           "^=",           "?:",           "||",
   6.788 -        "&&",           "|",            "^",            "&",            "!=",
   6.789 -        "==",           ">=",           ">",            "<=",           "<",
   6.790 -        "instanceof",   "<<",           ">>",           "<<<",          "+",
   6.791 -        "-",            "/",            "%",            "*",            "cast",
   6.792 -        "+",            "-",            "!",            "~",            "++",
   6.793 -        "--",           "new",          "new",          "new",          "++",
   6.794 -        "--",           "field",        "method",       "[]",           "new",
   6.795 -        "++",           "--",           null,           null,           null,
   6.796 -
   6.797 -        "convert",      "expr",         "array",        "goto",         null,
   6.798 -
   6.799 -        "Identifier",   "Boolean",      "Byte",         "Char",         "Short",
   6.800 -        "Integer",              "Long",         "Float",        "Double",       "String",
   6.801 -
   6.802 -        "byte",         "char",         "short",        "int",          "long",
   6.803 -        "float",        "double",       "void",         "boolean",      null,
   6.804 -
   6.805 -        "true",         "false",        "this",         "super",        "null",
   6.806 -        null,           null,           null,           null,           null,
   6.807 -
   6.808 -        "if",           "else",         "for",          "while",        "do",
   6.809 -        "switch",       "case",         "default",      "break",        "continue",
   6.810 -        "return",       "try",          "catch",        "finally",      "throw",
   6.811 -        "stat",         "expression",   "declaration",  "declaration",  null,
   6.812 -
   6.813 -        "import",       "class",        "extends",      "implements",   "interface",
   6.814 -        "package",      null,           null,           null,           null,
   6.815 -
   6.816 -        "private",      "public",       "protected",    "const",        "static",
   6.817 -        "transient",    "synchronized", "native",       "final",        "volatile",
   6.818 -        "abstract",     null,           null,           null,           null,
   6.819 -
   6.820 -        ";",            ":",            "?",            "{",            "}",
   6.821 -        "(",            ")",            "[",            "]",            "throws",
   6.822 -        "error",        "comment",      "type",         "length",       "inline-return",
   6.823 -        "inline-method", "inline-new",
   6.824 -        "method", "field", "stack", "locals", "CPINDEX", "CPName", "SIGN",
   6.825 -        "bits", "INF", "NaN", "InnerClass", "of", "synthetic"
   6.826 -    };
   6.827 -    
   6.828 +*/
   6.829      static class AnnotationParser {
   6.830  
   6.831          private final boolean textual;
   6.832 @@ -1332,15 +535,11 @@
   6.833          private int super_class;
   6.834          private int interfaces_count;
   6.835          private int[] interfaces = new int[0];
   6.836 -        private int fields_count;
   6.837          private FieldData[] fields;
   6.838 -        private int methods_count;
   6.839          private MethodData[] methods;
   6.840          private InnerClassData[] innerClasses;
   6.841          private int attributes_count;
   6.842          private AttrData[] attrs;
   6.843 -        private String classname;
   6.844 -        private String superclassname;
   6.845          private int source_cpx = 0;
   6.846          private byte tags[];
   6.847          private Hashtable indexHashAscii = new Hashtable();
   6.848 @@ -2062,7 +1261,7 @@
   6.849          int name_index;
   6.850          int descriptor_index;
   6.851          int attributes_count;
   6.852 -        int value_cpx = 0;
   6.853 +        int value_cpx = -1;
   6.854          boolean isSynthetic = false;
   6.855          boolean isDeprecated = false;
   6.856          Vector attrs;
   6.857 @@ -2183,11 +1382,8 @@
   6.858              return isDeprecated;
   6.859          }
   6.860  
   6.861 -        /**
   6.862 -         * Returns index of constant value in cpool.
   6.863 -         */
   6.864 -        public int getConstantValueIndex() {
   6.865 -            return (value_cpx);
   6.866 +        public boolean hasConstantValue() {
   6.867 +            return value_cpx != -1;
   6.868          }
   6.869  
   6.870          /**
   6.871 @@ -2806,6 +2002,10 @@
   6.872              lastFrameByteCodeOffset = -1;
   6.873              advanceBy(0);
   6.874          }
   6.875 +        
   6.876 +        public boolean isEmpty() {
   6.877 +            return stackMapTable.length == 0;
   6.878 +        }
   6.879  
   6.880          public String getFrameAsString() {
   6.881              return (nextFrameIndex == 0)
     7.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Feb 16 20:06:03 2014 +0100
     7.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Feb 19 08:10:04 2014 +0100
     7.3 @@ -153,6 +153,11 @@
     7.4          }
     7.5          for (FieldData v : jc.getFields()) {
     7.6              if (v.isStatic()) {
     7.7 +                if ((v.access & ACC_FINAL) != 0 && v.hasConstantValue()) {
     7.8 +                    if (v.getInternalSig().length() == 1 || v.getInternalSig().equals("Ljava/lang/String;")) {
     7.9 +                        continue;
    7.10 +                    }
    7.11 +                }
    7.12                  out.append("\n  CLS.fld_").append(v.getName()).append(initField(v));
    7.13                  out.append("\n  c._").append(v.getName()).append(" = function (v) {")
    7.14                     .append("  if (arguments.length == 1) CLS.fld_").append(v.getName())
    7.15 @@ -322,11 +327,19 @@
    7.16              out.append("  var ").append(" lcA0 = this;\n");
    7.17          }
    7.18  
    7.19 -        int lastStackFrame = -1;
    7.20 +        int lastStackFrame;
    7.21          TrapData[] previousTrap = null;
    7.22          boolean wide = false;
    7.23 +        boolean didBranches;
    7.24 +        if (stackMapIterator.isEmpty()) {
    7.25 +            didBranches = false;
    7.26 +            lastStackFrame = 0;
    7.27 +        } else {
    7.28 +            didBranches = true;
    7.29 +            lastStackFrame = -1;
    7.30 +            out.append("\n  var gt = 0;\n");
    7.31 +        }
    7.32          
    7.33 -        out.append("\n  var gt = 0;\n");
    7.34          int openBraces = 0;
    7.35          int topMostLabel = 0;
    7.36          for (int i = 0; i < byteCodes.length; i++) {
    7.37 @@ -340,6 +353,7 @@
    7.38                  }
    7.39              }
    7.40              if (lastStackFrame != stackMapIterator.getFrameIndex()) {
    7.41 +                smapper.flush(out);
    7.42                  if (i != 0) {
    7.43                      out.append("    }\n");
    7.44                  }
    7.45 @@ -367,72 +381,71 @@
    7.46              final int c = readUByte(byteCodes, i);
    7.47              switch (c) {
    7.48                  case opc_aload_0:
    7.49 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(0));
    7.50 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(0));
    7.51                      break;
    7.52                  case opc_iload_0:
    7.53 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(0));
    7.54 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(0));
    7.55                      break;
    7.56                  case opc_lload_0:
    7.57 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(0));
    7.58 +                    smapper.assign(out, VarType.LONG, lmapper.getL(0));
    7.59                      break;
    7.60                  case opc_fload_0:
    7.61 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(0));
    7.62 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(0));
    7.63                      break;
    7.64                  case opc_dload_0:
    7.65 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(0));
    7.66 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(0));
    7.67                      break;
    7.68                  case opc_aload_1:
    7.69 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(1));
    7.70 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(1));
    7.71                      break;
    7.72                  case opc_iload_1:
    7.73 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(1));
    7.74 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(1));
    7.75                      break;
    7.76                  case opc_lload_1:
    7.77 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(1));
    7.78 +                    smapper.assign(out, VarType.LONG, lmapper.getL(1));
    7.79                      break;
    7.80                  case opc_fload_1:
    7.81 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(1));
    7.82 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(1));
    7.83                      break;
    7.84                  case opc_dload_1:
    7.85 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(1));
    7.86 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(1));
    7.87                      break;
    7.88                  case opc_aload_2:
    7.89 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(2));
    7.90 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(2));
    7.91                      break;
    7.92                  case opc_iload_2:
    7.93 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(2));
    7.94 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(2));
    7.95                      break;
    7.96                  case opc_lload_2:
    7.97 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(2));
    7.98 +                    smapper.assign(out, VarType.LONG, lmapper.getL(2));
    7.99                      break;
   7.100                  case opc_fload_2:
   7.101 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(2));
   7.102 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(2));
   7.103                      break;
   7.104                  case opc_dload_2:
   7.105 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(2));
   7.106 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(2));
   7.107                      break;
   7.108                  case opc_aload_3:
   7.109 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(3));
   7.110 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(3));
   7.111                      break;
   7.112                  case opc_iload_3:
   7.113 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(3));
   7.114 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(3));
   7.115                      break;
   7.116                  case opc_lload_3:
   7.117 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(3));
   7.118 +                    smapper.assign(out, VarType.LONG, lmapper.getL(3));
   7.119                      break;
   7.120                  case opc_fload_3:
   7.121 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(3));
   7.122 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(3));
   7.123                      break;
   7.124                  case opc_dload_3:
   7.125 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(3));
   7.126 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(3));
   7.127                      break;
   7.128                  case opc_iload: {
   7.129                      ++i;
   7.130                      final int indx = wide ? readUShort(byteCodes, i++)
   7.131                                            : readUByte(byteCodes, i);
   7.132                      wide = false;
   7.133 -                    emit(out, "var @1 = @2;",
   7.134 -                         smapper.pushI(), lmapper.getI(indx));
   7.135 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(indx));
   7.136                      break;
   7.137                  }
   7.138                  case opc_lload: {
   7.139 @@ -440,8 +453,7 @@
   7.140                      final int indx = wide ? readUShort(byteCodes, i++)
   7.141                                            : readUByte(byteCodes, i);
   7.142                      wide = false;
   7.143 -                    emit(out, "var @1 = @2;",
   7.144 -                         smapper.pushL(), lmapper.getL(indx));
   7.145 +                    smapper.assign(out, VarType.LONG, lmapper.getL(indx));
   7.146                      break;
   7.147                  }
   7.148                  case opc_fload: {
   7.149 @@ -449,8 +461,7 @@
   7.150                      final int indx = wide ? readUShort(byteCodes, i++)
   7.151                                            : readUByte(byteCodes, i);
   7.152                      wide = false;
   7.153 -                    emit(out, "var @1 = @2;",
   7.154 -                         smapper.pushF(), lmapper.getF(indx));
   7.155 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(indx));
   7.156                      break;
   7.157                  }
   7.158                  case opc_dload: {
   7.159 @@ -458,8 +469,7 @@
   7.160                      final int indx = wide ? readUShort(byteCodes, i++)
   7.161                                            : readUByte(byteCodes, i);
   7.162                      wide = false;
   7.163 -                    emit(out, "var @1 = @2;",
   7.164 -                         smapper.pushD(), lmapper.getD(indx));
   7.165 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(indx));
   7.166                      break;
   7.167                  }
   7.168                  case opc_aload: {
   7.169 @@ -467,8 +477,7 @@
   7.170                      final int indx = wide ? readUShort(byteCodes, i++)
   7.171                                            : readUByte(byteCodes, i);
   7.172                      wide = false;
   7.173 -                    emit(out, "var @1 = @2;",
   7.174 -                         smapper.pushA(), lmapper.getA(indx));
   7.175 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(indx));
   7.176                      break;
   7.177                  }
   7.178                  case opc_istore: {
   7.179 @@ -476,7 +485,7 @@
   7.180                      final int indx = wide ? readUShort(byteCodes, i++)
   7.181                                            : readUByte(byteCodes, i);
   7.182                      wide = false;
   7.183 -                    emit(out, "var @1 = @2;",
   7.184 +                    emit(smapper, out, "var @1 = @2;",
   7.185                           lmapper.setI(indx), smapper.popI());
   7.186                      break;
   7.187                  }
   7.188 @@ -485,7 +494,7 @@
   7.189                      final int indx = wide ? readUShort(byteCodes, i++)
   7.190                                            : readUByte(byteCodes, i);
   7.191                      wide = false;
   7.192 -                    emit(out, "var @1 = @2;",
   7.193 +                    emit(smapper, out, "var @1 = @2;",
   7.194                           lmapper.setL(indx), smapper.popL());
   7.195                      break;
   7.196                  }
   7.197 @@ -494,7 +503,7 @@
   7.198                      final int indx = wide ? readUShort(byteCodes, i++)
   7.199                                            : readUByte(byteCodes, i);
   7.200                      wide = false;
   7.201 -                    emit(out, "var @1 = @2;",
   7.202 +                    emit(smapper, out, "var @1 = @2;",
   7.203                           lmapper.setF(indx), smapper.popF());
   7.204                      break;
   7.205                  }
   7.206 @@ -503,7 +512,7 @@
   7.207                      final int indx = wide ? readUShort(byteCodes, i++)
   7.208                                            : readUByte(byteCodes, i);
   7.209                      wide = false;
   7.210 -                    emit(out, "var @1 = @2;",
   7.211 +                    emit(smapper, out, "var @1 = @2;",
   7.212                           lmapper.setD(indx), smapper.popD());
   7.213                      break;
   7.214                  }
   7.215 @@ -512,181 +521,181 @@
   7.216                      final int indx = wide ? readUShort(byteCodes, i++)
   7.217                                            : readUByte(byteCodes, i);
   7.218                      wide = false;
   7.219 -                    emit(out, "var @1 = @2;",
   7.220 +                    emit(smapper, out, "var @1 = @2;",
   7.221                           lmapper.setA(indx), smapper.popA());
   7.222                      break;
   7.223                  }
   7.224                  case opc_astore_0:
   7.225 -                    emit(out, "var @1 = @2;", lmapper.setA(0), smapper.popA());
   7.226 +                    emit(smapper, out, "var @1 = @2;", lmapper.setA(0), smapper.popA());
   7.227                      break;
   7.228                  case opc_istore_0:
   7.229 -                    emit(out, "var @1 = @2;", lmapper.setI(0), smapper.popI());
   7.230 +                    emit(smapper, out, "var @1 = @2;", lmapper.setI(0), smapper.popI());
   7.231                      break;
   7.232                  case opc_lstore_0:
   7.233 -                    emit(out, "var @1 = @2;", lmapper.setL(0), smapper.popL());
   7.234 +                    emit(smapper, out, "var @1 = @2;", lmapper.setL(0), smapper.popL());
   7.235                      break;
   7.236                  case opc_fstore_0:
   7.237 -                    emit(out, "var @1 = @2;", lmapper.setF(0), smapper.popF());
   7.238 +                    emit(smapper, out, "var @1 = @2;", lmapper.setF(0), smapper.popF());
   7.239                      break;
   7.240                  case opc_dstore_0:
   7.241 -                    emit(out, "var @1 = @2;", lmapper.setD(0), smapper.popD());
   7.242 +                    emit(smapper, out, "var @1 = @2;", lmapper.setD(0), smapper.popD());
   7.243                      break;
   7.244                  case opc_astore_1:
   7.245 -                    emit(out, "var @1 = @2;", lmapper.setA(1), smapper.popA());
   7.246 +                    emit(smapper, out, "var @1 = @2;", lmapper.setA(1), smapper.popA());
   7.247                      break;
   7.248                  case opc_istore_1:
   7.249 -                    emit(out, "var @1 = @2;", lmapper.setI(1), smapper.popI());
   7.250 +                    emit(smapper, out, "var @1 = @2;", lmapper.setI(1), smapper.popI());
   7.251                      break;
   7.252                  case opc_lstore_1:
   7.253 -                    emit(out, "var @1 = @2;", lmapper.setL(1), smapper.popL());
   7.254 +                    emit(smapper, out, "var @1 = @2;", lmapper.setL(1), smapper.popL());
   7.255                      break;
   7.256                  case opc_fstore_1:
   7.257 -                    emit(out, "var @1 = @2;", lmapper.setF(1), smapper.popF());
   7.258 +                    emit(smapper, out, "var @1 = @2;", lmapper.setF(1), smapper.popF());
   7.259                      break;
   7.260                  case opc_dstore_1:
   7.261 -                    emit(out, "var @1 = @2;", lmapper.setD(1), smapper.popD());
   7.262 +                    emit(smapper, out, "var @1 = @2;", lmapper.setD(1), smapper.popD());
   7.263                      break;
   7.264                  case opc_astore_2:
   7.265 -                    emit(out, "var @1 = @2;", lmapper.setA(2), smapper.popA());
   7.266 +                    emit(smapper, out, "var @1 = @2;", lmapper.setA(2), smapper.popA());
   7.267                      break;
   7.268                  case opc_istore_2:
   7.269 -                    emit(out, "var @1 = @2;", lmapper.setI(2), smapper.popI());
   7.270 +                    emit(smapper, out, "var @1 = @2;", lmapper.setI(2), smapper.popI());
   7.271                      break;
   7.272                  case opc_lstore_2:
   7.273 -                    emit(out, "var @1 = @2;", lmapper.setL(2), smapper.popL());
   7.274 +                    emit(smapper, out, "var @1 = @2;", lmapper.setL(2), smapper.popL());
   7.275                      break;
   7.276                  case opc_fstore_2:
   7.277 -                    emit(out, "var @1 = @2;", lmapper.setF(2), smapper.popF());
   7.278 +                    emit(smapper, out, "var @1 = @2;", lmapper.setF(2), smapper.popF());
   7.279                      break;
   7.280                  case opc_dstore_2:
   7.281 -                    emit(out, "var @1 = @2;", lmapper.setD(2), smapper.popD());
   7.282 +                    emit(smapper, out, "var @1 = @2;", lmapper.setD(2), smapper.popD());
   7.283                      break;
   7.284                  case opc_astore_3:
   7.285 -                    emit(out, "var @1 = @2;", lmapper.setA(3), smapper.popA());
   7.286 +                    emit(smapper, out, "var @1 = @2;", lmapper.setA(3), smapper.popA());
   7.287                      break;
   7.288                  case opc_istore_3:
   7.289 -                    emit(out, "var @1 = @2;", lmapper.setI(3), smapper.popI());
   7.290 +                    emit(smapper, out, "var @1 = @2;", lmapper.setI(3), smapper.popI());
   7.291                      break;
   7.292                  case opc_lstore_3:
   7.293 -                    emit(out, "var @1 = @2;", lmapper.setL(3), smapper.popL());
   7.294 +                    emit(smapper, out, "var @1 = @2;", lmapper.setL(3), smapper.popL());
   7.295                      break;
   7.296                  case opc_fstore_3:
   7.297 -                    emit(out, "var @1 = @2;", lmapper.setF(3), smapper.popF());
   7.298 +                    emit(smapper, out, "var @1 = @2;", lmapper.setF(3), smapper.popF());
   7.299                      break;
   7.300                  case opc_dstore_3:
   7.301 -                    emit(out, "var @1 = @2;", lmapper.setD(3), smapper.popD());
   7.302 +                    emit(smapper, out, "var @1 = @2;", lmapper.setD(3), smapper.popD());
   7.303                      break;
   7.304                  case opc_iadd:
   7.305 -                    emit(out, "@1 = @1.add32(@2);", smapper.getI(1), smapper.popI());
   7.306 +                    smapper.replace(out, VarType.INTEGER, "(@1).add32(@2)", smapper.getI(1), smapper.popI());
   7.307                      break;
   7.308                  case opc_ladd:
   7.309 -                    emit(out, "@1 = @1.add64(@2);", smapper.getL(1), smapper.popL());
   7.310 +                    smapper.replace(out, VarType.LONG, "(@1).add64(@2)", smapper.getL(1), smapper.popL());
   7.311                      break;
   7.312                  case opc_fadd:
   7.313 -                    emit(out, "@1 += @2;", smapper.getF(1), smapper.popF());
   7.314 +                    smapper.replace(out, VarType.FLOAT, "(@1 + @2)", smapper.getF(1), smapper.popF());
   7.315                      break;
   7.316                  case opc_dadd:
   7.317 -                    emit(out, "@1 += @2;", smapper.getD(1), smapper.popD());
   7.318 +                    smapper.replace(out, VarType.DOUBLE, "(@1 + @2)", smapper.getD(1), smapper.popD());
   7.319                      break;
   7.320                  case opc_isub:
   7.321 -                    emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI());
   7.322 +                    smapper.replace(out, VarType.INTEGER, "(@1).sub32(@2)", smapper.getI(1), smapper.popI());
   7.323                      break;
   7.324                  case opc_lsub:
   7.325 -                    emit(out, "@1 = @1.sub64(@2);", smapper.getL(1), smapper.popL());
   7.326 +                    smapper.replace(out, VarType.LONG, "(@1).sub64(@2)", smapper.getL(1), smapper.popL());
   7.327                      break;
   7.328                  case opc_fsub:
   7.329 -                    emit(out, "@1 -= @2;", smapper.getF(1), smapper.popF());
   7.330 +                    smapper.replace(out, VarType.FLOAT, "(@1 - @2)", smapper.getF(1), smapper.popF());
   7.331                      break;
   7.332                  case opc_dsub:
   7.333 -                    emit(out, "@1 -= @2;", smapper.getD(1), smapper.popD());
   7.334 +                    smapper.replace(out, VarType.DOUBLE, "(@1 - @2)", smapper.getD(1), smapper.popD());
   7.335                      break;
   7.336                  case opc_imul:
   7.337 -                    emit(out, "@1 = @1.mul32(@2);", smapper.getI(1), smapper.popI());
   7.338 +                    smapper.replace(out, VarType.INTEGER, "(@1).mul32(@2)", smapper.getI(1), smapper.popI());
   7.339                      break;
   7.340                  case opc_lmul:
   7.341 -                    emit(out, "@1 = @1.mul64(@2);", smapper.getL(1), smapper.popL());
   7.342 +                    smapper.replace(out, VarType.LONG, "(@1).mul64(@2)", smapper.getL(1), smapper.popL());
   7.343                      break;
   7.344                  case opc_fmul:
   7.345 -                    emit(out, "@1 *= @2;", smapper.getF(1), smapper.popF());
   7.346 +                    smapper.replace(out, VarType.FLOAT, "(@1 * @2)", smapper.getF(1), smapper.popF());
   7.347                      break;
   7.348                  case opc_dmul:
   7.349 -                    emit(out, "@1 *= @2;", smapper.getD(1), smapper.popD());
   7.350 +                    smapper.replace(out, VarType.DOUBLE, "(@1 * @2)", smapper.getD(1), smapper.popD());
   7.351                      break;
   7.352                  case opc_idiv:
   7.353 -                    emit(out, "@1 = @1.div32(@2);",
   7.354 +                    smapper.replace(out, VarType.INTEGER, "(@1).div32(@2)",
   7.355                           smapper.getI(1), smapper.popI());
   7.356                      break;
   7.357                  case opc_ldiv:
   7.358 -                    emit(out, "@1 = @1.div64(@2);",
   7.359 +                    smapper.replace(out, VarType.LONG, "(@1).div64(@2)",
   7.360                           smapper.getL(1), smapper.popL());
   7.361                      break;
   7.362                  case opc_fdiv:
   7.363 -                    emit(out, "@1 /= @2;", smapper.getF(1), smapper.popF());
   7.364 +                    smapper.replace(out, VarType.FLOAT, "(@1 / @2)", smapper.getF(1), smapper.popF());
   7.365                      break;
   7.366                  case opc_ddiv:
   7.367 -                    emit(out, "@1 /= @2;", smapper.getD(1), smapper.popD());
   7.368 +                    smapper.replace(out, VarType.DOUBLE, "(@1 / @2)", smapper.getD(1), smapper.popD());
   7.369                      break;
   7.370                  case opc_irem:
   7.371 -                    emit(out, "@1 = @1.mod32(@2);",
   7.372 +                    smapper.replace(out, VarType.INTEGER, "(@1).mod32(@2)",
   7.373                           smapper.getI(1), smapper.popI());
   7.374                      break;
   7.375                  case opc_lrem:
   7.376 -                    emit(out, "@1 = @1.mod64(@2);",
   7.377 +                    smapper.replace(out, VarType.LONG, "(@1).mod64(@2)",
   7.378                           smapper.getL(1), smapper.popL());
   7.379                      break;
   7.380                  case opc_frem:
   7.381 -                    emit(out, "@1 %= @2;", smapper.getF(1), smapper.popF());
   7.382 +                    smapper.replace(out, VarType.FLOAT, "(@1 % @2)", smapper.getF(1), smapper.popF());
   7.383                      break;
   7.384                  case opc_drem:
   7.385 -                    emit(out, "@1 %= @2;", smapper.getD(1), smapper.popD());
   7.386 +                    smapper.replace(out, VarType.DOUBLE, "(@1 % @2)", smapper.getD(1), smapper.popD());
   7.387                      break;
   7.388                  case opc_iand:
   7.389 -                    emit(out, "@1 &= @2;", smapper.getI(1), smapper.popI());
   7.390 +                    smapper.replace(out, VarType.INTEGER, "(@1 & @2)", smapper.getI(1), smapper.popI());
   7.391                      break;
   7.392                  case opc_land:
   7.393 -                    emit(out, "@1 = @1.and64(@2);", smapper.getL(1), smapper.popL());
   7.394 +                    smapper.replace(out, VarType.LONG, "(@1).and64(@2)", smapper.getL(1), smapper.popL());
   7.395                      break;
   7.396                  case opc_ior:
   7.397 -                    emit(out, "@1 |= @2;", smapper.getI(1), smapper.popI());
   7.398 +                    smapper.replace(out, VarType.INTEGER, "(@1 | @2)", smapper.getI(1), smapper.popI());
   7.399                      break;
   7.400                  case opc_lor:
   7.401 -                    emit(out, "@1 = @1.or64(@2);", smapper.getL(1), smapper.popL());
   7.402 +                    smapper.replace(out, VarType.LONG, "(@1).or64(@2)", smapper.getL(1), smapper.popL());
   7.403                      break;
   7.404                  case opc_ixor:
   7.405 -                    emit(out, "@1 ^= @2;", smapper.getI(1), smapper.popI());
   7.406 +                    smapper.replace(out, VarType.INTEGER, "(@1 ^ @2)", smapper.getI(1), smapper.popI());
   7.407                      break;
   7.408                  case opc_lxor:
   7.409 -                    emit(out, "@1 = @1.xor64(@2);", smapper.getL(1), smapper.popL());
   7.410 +                    smapper.replace(out, VarType.LONG, "(@1).xor64(@2)", smapper.getL(1), smapper.popL());
   7.411                      break;
   7.412                  case opc_ineg:
   7.413 -                    emit(out, "@1 = @1.neg32();", smapper.getI(0));
   7.414 +                    smapper.replace(out, VarType.INTEGER, "(@1).neg32()", smapper.getI(0));
   7.415                      break;
   7.416                  case opc_lneg:
   7.417 -                    emit(out, "@1 = @1.neg64();", smapper.getL(0));
   7.418 +                    smapper.replace(out, VarType.LONG, "(@1).neg64()", smapper.getL(0));
   7.419                      break;
   7.420                  case opc_fneg:
   7.421 -                    emit(out, "@1 = -@1;", smapper.getF(0));
   7.422 +                    smapper.replace(out, VarType.FLOAT, "(-@1)", smapper.getF(0));
   7.423                      break;
   7.424                  case opc_dneg:
   7.425 -                    emit(out, "@1 = -@1;", smapper.getD(0));
   7.426 +                    smapper.replace(out, VarType.DOUBLE, "(-@1)", smapper.getD(0));
   7.427                      break;
   7.428                  case opc_ishl:
   7.429 -                    emit(out, "@1 <<= @2;", smapper.getI(1), smapper.popI());
   7.430 +                    smapper.replace(out, VarType.INTEGER, "(@1 << @2)", smapper.getI(1), smapper.popI());
   7.431                      break;
   7.432                  case opc_lshl:
   7.433 -                    emit(out, "@1 = @1.shl64(@2);", smapper.getL(1), smapper.popI());
   7.434 +                    smapper.replace(out, VarType.LONG, "(@1).shl64(@2)", smapper.getL(1), smapper.popI());
   7.435                      break;
   7.436                  case opc_ishr:
   7.437 -                    emit(out, "@1 >>= @2;", smapper.getI(1), smapper.popI());
   7.438 +                    smapper.replace(out, VarType.INTEGER, "(@1 >> @2)", smapper.getI(1), smapper.popI());
   7.439                      break;
   7.440                  case opc_lshr:
   7.441 -                    emit(out, "@1 = @1.shr64(@2);", smapper.getL(1), smapper.popI());
   7.442 +                    smapper.replace(out, VarType.LONG, "(@1).shr64(@2)", smapper.getL(1), smapper.popI());
   7.443                      break;
   7.444                  case opc_iushr:
   7.445 -                    emit(out, "@1 >>>= @2;", smapper.getI(1), smapper.popI());
   7.446 +                    smapper.replace(out, VarType.INTEGER, "(@1 >>> @2)", smapper.getI(1), smapper.popI());
   7.447                      break;
   7.448                  case opc_lushr:
   7.449 -                    emit(out, "@1 = @1.ushr64(@2);", smapper.getL(1), smapper.popI());
   7.450 +                    smapper.replace(out, VarType.LONG, "(@1).ushr64(@2)", smapper.getL(1), smapper.popI());
   7.451                      break;
   7.452                  case opc_iinc: {
   7.453                      ++i;
   7.454 @@ -697,132 +706,132 @@
   7.455                                              : byteCodes[i];
   7.456                      wide = false;
   7.457                      if (incrBy == 1) {
   7.458 -                        emit(out, "@1++;", lmapper.getI(varIndx));
   7.459 +                        emit(smapper, out, "@1++;", lmapper.getI(varIndx));
   7.460                      } else {
   7.461 -                        emit(out, "@1 += @2;",
   7.462 +                        emit(smapper, out, "@1 += @2;",
   7.463                               lmapper.getI(varIndx),
   7.464                               Integer.toString(incrBy));
   7.465                      }
   7.466                      break;
   7.467                  }
   7.468                  case opc_return:
   7.469 -                    emit(out, "return;");
   7.470 +                    emit(smapper, out, "return;");
   7.471                      break;
   7.472                  case opc_ireturn:
   7.473 -                    emit(out, "return @1;", smapper.popI());
   7.474 +                    emit(smapper, out, "return @1;", smapper.popI());
   7.475                      break;
   7.476                  case opc_lreturn:
   7.477 -                    emit(out, "return @1;", smapper.popL());
   7.478 +                    emit(smapper, out, "return @1;", smapper.popL());
   7.479                      break;
   7.480                  case opc_freturn:
   7.481 -                    emit(out, "return @1;", smapper.popF());
   7.482 +                    emit(smapper, out, "return @1;", smapper.popF());
   7.483                      break;
   7.484                  case opc_dreturn:
   7.485 -                    emit(out, "return @1;", smapper.popD());
   7.486 +                    emit(smapper, out, "return @1;", smapper.popD());
   7.487                      break;
   7.488                  case opc_areturn:
   7.489 -                    emit(out, "return @1;", smapper.popA());
   7.490 +                    emit(smapper, out, "return @1;", smapper.popA());
   7.491                      break;
   7.492                  case opc_i2l:
   7.493 -                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushL());
   7.494 +                    smapper.replace(out, VarType.LONG, "@1", smapper.getI(0));
   7.495                      break;
   7.496                  case opc_i2f:
   7.497 -                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushF());
   7.498 +                    smapper.replace(out, VarType.FLOAT, "@1", smapper.getI(0));
   7.499                      break;
   7.500                  case opc_i2d:
   7.501 -                    emit(out, "var @2 = @1;", smapper.popI(), smapper.pushD());
   7.502 +                    smapper.replace(out, VarType.DOUBLE, "@1", smapper.getI(0));
   7.503                      break;
   7.504                  case opc_l2i:
   7.505 -                    emit(out, "var @2 = @1.toInt32();", smapper.popL(), smapper.pushI());
   7.506 +                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()", smapper.getL(0));
   7.507                      break;
   7.508                      // max int check?
   7.509                  case opc_l2f:
   7.510 -                    emit(out, "var @2 = @1.toFP();", smapper.popL(), smapper.pushF());
   7.511 +                    smapper.replace(out, VarType.FLOAT, "(@1).toFP()", smapper.getL(0));
   7.512                      break;
   7.513                  case opc_l2d:
   7.514 -                    emit(out, "var @2 = @1.toFP();", smapper.popL(), smapper.pushD());
   7.515 +                    smapper.replace(out, VarType.DOUBLE, "(@1).toFP()", smapper.getL(0));
   7.516                      break;
   7.517                  case opc_f2d:
   7.518 -                    emit(out, "var @2 = @1;", smapper.popF(), smapper.pushD());
   7.519 +                    smapper.replace(out, VarType.DOUBLE, "@1",
   7.520 +                         smapper.getF(0));
   7.521                      break;
   7.522                  case opc_d2f:
   7.523 -                    emit(out, "var @2 = @1;", smapper.popD(), smapper.pushF());
   7.524 +                    smapper.replace(out, VarType.FLOAT, "@1",
   7.525 +                         smapper.getD(0));
   7.526                      break;
   7.527                  case opc_f2i:
   7.528 -                    emit(out, "var @2 = @1.toInt32();",
   7.529 -                         smapper.popF(), smapper.pushI());
   7.530 +                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()",
   7.531 +                         smapper.getF(0));
   7.532                      break;
   7.533                  case opc_f2l:
   7.534 -                    emit(out, "var @2 = @1.toLong();",
   7.535 -                         smapper.popF(), smapper.pushL());
   7.536 +                    smapper.replace(out, VarType.LONG, "(@1).toLong()",
   7.537 +                         smapper.getF(0));
   7.538                      break;
   7.539                  case opc_d2i:
   7.540 -                    emit(out, "var @2 = @1.toInt32();",
   7.541 -                         smapper.popD(), smapper.pushI());
   7.542 +                    smapper.replace(out, VarType.INTEGER, "(@1).toInt32()",
   7.543 +                         smapper.getD(0));
   7.544                      break;
   7.545                  case opc_d2l:
   7.546 -                    emit(out, "var @2 = @1.toLong();",
   7.547 -                         smapper.popD(), smapper.pushL());
   7.548 +                    smapper.replace(out, VarType.LONG, "(@1).toLong()", smapper.getD(0));
   7.549                      break;
   7.550                  case opc_i2b:
   7.551 -                    emit(out, "var @1 = @1.toInt8();", smapper.getI(0));
   7.552 +                    smapper.replace(out, VarType.INTEGER, "(@1).toInt8()", smapper.getI(0));
   7.553                      break;
   7.554                  case opc_i2c:
   7.555 -                    out.append("{ /* number conversion */ }");
   7.556                      break;
   7.557                  case opc_i2s:
   7.558 -                    emit(out, "var @1 = @1.toInt16();", smapper.getI(0));
   7.559 +                    smapper.replace(out, VarType.INTEGER, "(@1).toInt16()", smapper.getI(0));
   7.560                      break;
   7.561                  case opc_aconst_null:
   7.562 -                    emit(out, "var @1 = null;", smapper.pushA());
   7.563 +                    smapper.assign(out, VarType.REFERENCE, "null");
   7.564                      break;
   7.565                  case opc_iconst_m1:
   7.566 -                    emit(out, "var @1 = -1;", smapper.pushI());
   7.567 +                    smapper.assign(out, VarType.INTEGER, "-1");
   7.568                      break;
   7.569                  case opc_iconst_0:
   7.570 -                    emit(out, "var @1 = 0;", smapper.pushI());
   7.571 +                    smapper.assign(out, VarType.INTEGER, "0");
   7.572                      break;
   7.573                  case opc_dconst_0:
   7.574 -                    emit(out, "var @1 = 0;", smapper.pushD());
   7.575 +                    smapper.assign(out, VarType.DOUBLE, "0");
   7.576                      break;
   7.577                  case opc_lconst_0:
   7.578 -                    emit(out, "var @1 = 0;", smapper.pushL());
   7.579 +                    smapper.assign(out, VarType.LONG, "0");
   7.580                      break;
   7.581                  case opc_fconst_0:
   7.582 -                    emit(out, "var @1 = 0;", smapper.pushF());
   7.583 +                    smapper.assign(out, VarType.FLOAT, "0");
   7.584                      break;
   7.585                  case opc_iconst_1:
   7.586 -                    emit(out, "var @1 = 1;", smapper.pushI());
   7.587 +                    smapper.assign(out, VarType.INTEGER, "1");
   7.588                      break;
   7.589                  case opc_lconst_1:
   7.590 -                    emit(out, "var @1 = 1;", smapper.pushL());
   7.591 +                    smapper.assign(out, VarType.LONG, "1");
   7.592                      break;
   7.593                  case opc_fconst_1:
   7.594 -                    emit(out, "var @1 = 1;", smapper.pushF());
   7.595 +                    smapper.assign(out, VarType.FLOAT, "1");
   7.596                      break;
   7.597                  case opc_dconst_1:
   7.598 -                    emit(out, "var @1 = 1;", smapper.pushD());
   7.599 +                    smapper.assign(out, VarType.DOUBLE, "1");
   7.600                      break;
   7.601                  case opc_iconst_2:
   7.602 -                    emit(out, "var @1 = 2;", smapper.pushI());
   7.603 +                    smapper.assign(out, VarType.INTEGER, "2");
   7.604                      break;
   7.605                  case opc_fconst_2:
   7.606 -                    emit(out, "var @1 = 2;", smapper.pushF());
   7.607 +                    smapper.assign(out, VarType.FLOAT, "2");
   7.608                      break;
   7.609                  case opc_iconst_3:
   7.610 -                    emit(out, "var @1 = 3;", smapper.pushI());
   7.611 +                    smapper.assign(out, VarType.INTEGER, "3");
   7.612                      break;
   7.613                  case opc_iconst_4:
   7.614 -                    emit(out, "var @1 = 4;", smapper.pushI());
   7.615 +                    smapper.assign(out, VarType.INTEGER, "4");
   7.616                      break;
   7.617                  case opc_iconst_5:
   7.618 -                    emit(out, "var @1 = 5;", smapper.pushI());
   7.619 +                    smapper.assign(out, VarType.INTEGER, "5");
   7.620                      break;
   7.621                  case opc_ldc: {
   7.622                      int indx = readUByte(byteCodes, ++i);
   7.623                      String v = encodeConstant(indx);
   7.624                      int type = VarType.fromConstantType(jc.getTag(indx));
   7.625 -                    emit(out, "var @1 = @2;", smapper.pushT(type), v);
   7.626 +                    smapper.assign(out, type, v);
   7.627                      break;
   7.628                  }
   7.629                  case opc_ldc_w:
   7.630 @@ -835,116 +844,120 @@
   7.631                          final Long lv = new Long(v);
   7.632                          final int low = (int)(lv.longValue() & 0xFFFFFFFF);
   7.633                          final int hi = (int)(lv.longValue() >> 32);
   7.634 -                        emit(out, "var @1 = 0x@3.next32(0x@2);", smapper.pushL(), 
   7.635 -                                Integer.toHexString(low), Integer.toHexString(hi));
   7.636 +                        if (hi == 0) {
   7.637 +                            smapper.assign(out, VarType.LONG, "0x" + Integer.toHexString(low));
   7.638 +                        } else {
   7.639 +                            smapper.assign(out, VarType.LONG,
   7.640 +                                "0x" + Integer.toHexString(hi) + ".next32(0x" + 
   7.641 +                                    Integer.toHexString(low) + ")"
   7.642 +                            );
   7.643 +                        }
   7.644                      } else {
   7.645 -                        emit(out, "var @1 = @2;", smapper.pushT(type), v);
   7.646 +                        smapper.assign(out, type, v);
   7.647                      }
   7.648                      break;
   7.649                  }
   7.650                  case opc_lcmp:
   7.651 -                    emit(out, "var @3 = @2.compare64(@1);",
   7.652 -                         smapper.popL(), smapper.popL(), smapper.pushI());
   7.653 +                    smapper.replace(out, VarType.INTEGER, "(@2).compare64(@1)", smapper.popL(), smapper.getL(0));
   7.654                      break;
   7.655                  case opc_fcmpl:
   7.656                  case opc_fcmpg:
   7.657 -                    emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
   7.658 -                         smapper.popF(), smapper.popF(), smapper.pushI());
   7.659 +                    smapper.replace(out, VarType.INTEGER, "(@2).compare(@1)", smapper.popF(), smapper.getF(0));
   7.660                      break;
   7.661                  case opc_dcmpl:
   7.662                  case opc_dcmpg:
   7.663 -                    emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
   7.664 -                         smapper.popD(), smapper.popD(), smapper.pushI());
   7.665 +                    smapper.replace(out, VarType.INTEGER, "(@2).compare(@1)", smapper.popD(), smapper.getD(0));
   7.666                      break;
   7.667                  case opc_if_acmpeq:
   7.668 -                    i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
   7.669 +                    i = generateIf(smapper, byteCodes, i, smapper.popA(), smapper.popA(),
   7.670                                     "===", topMostLabel);
   7.671                      break;
   7.672                  case opc_if_acmpne:
   7.673 -                    i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
   7.674 +                    i = generateIf(smapper, byteCodes, i, smapper.popA(), smapper.popA(),
   7.675                                     "!==", topMostLabel);
   7.676                      break;
   7.677                  case opc_if_icmpeq:
   7.678 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.679 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.680                                     "==", topMostLabel);
   7.681                      break;
   7.682                  case opc_ifeq: {
   7.683                      int indx = i + readShortArg(byteCodes, i);
   7.684 -                    emitIf(out, "if (@1 == 0) ",
   7.685 +                    emitIf(smapper, out, "if ((@1) == 0) ",
   7.686                           smapper.popI(), i, indx, topMostLabel);
   7.687                      i += 2;
   7.688                      break;
   7.689                  }
   7.690                  case opc_ifne: {
   7.691                      int indx = i + readShortArg(byteCodes, i);
   7.692 -                    emitIf(out, "if (@1 != 0) ",
   7.693 +                    emitIf(smapper, out, "if ((@1) != 0) ",
   7.694                           smapper.popI(), i, indx, topMostLabel);
   7.695                      i += 2;
   7.696                      break;
   7.697                  }
   7.698                  case opc_iflt: {
   7.699                      int indx = i + readShortArg(byteCodes, i);
   7.700 -                    emitIf(out, "if (@1 < 0) ",
   7.701 +                    emitIf(smapper, out, "if ((@1) < 0) ",
   7.702                           smapper.popI(), i, indx, topMostLabel);
   7.703                      i += 2;
   7.704                      break;
   7.705                  }
   7.706                  case opc_ifle: {
   7.707                      int indx = i + readShortArg(byteCodes, i);
   7.708 -                    emitIf(out, "if (@1 <= 0) ",
   7.709 +                    emitIf(smapper, out, "if ((@1) <= 0) ",
   7.710                           smapper.popI(), i, indx, topMostLabel);
   7.711                      i += 2;
   7.712                      break;
   7.713                  }
   7.714                  case opc_ifgt: {
   7.715                      int indx = i + readShortArg(byteCodes, i);
   7.716 -                    emitIf(out, "if (@1 > 0) ",
   7.717 +                    emitIf(smapper, out, "if ((@1) > 0) ",
   7.718                           smapper.popI(), i, indx, topMostLabel);
   7.719                      i += 2;
   7.720                      break;
   7.721                  }
   7.722                  case opc_ifge: {
   7.723                      int indx = i + readShortArg(byteCodes, i);
   7.724 -                    emitIf(out, "if (@1 >= 0) ",
   7.725 +                    emitIf(smapper, out, "if ((@1) >= 0) ",
   7.726                           smapper.popI(), i, indx, topMostLabel);
   7.727                      i += 2;
   7.728                      break;
   7.729                  }
   7.730                  case opc_ifnonnull: {
   7.731                      int indx = i + readShortArg(byteCodes, i);
   7.732 -                    emitIf(out, "if (@1 !== null) ",
   7.733 +                    emitIf(smapper, out, "if ((@1) !== null) ",
   7.734                           smapper.popA(), i, indx, topMostLabel);
   7.735                      i += 2;
   7.736                      break;
   7.737                  }
   7.738                  case opc_ifnull: {
   7.739                      int indx = i + readShortArg(byteCodes, i);
   7.740 -                    emitIf(out, "if (@1 === null) ",
   7.741 +                    emitIf(smapper, out, "if ((@1) === null) ",
   7.742                           smapper.popA(), i, indx, topMostLabel);
   7.743                      i += 2;
   7.744                      break;
   7.745                  }
   7.746                  case opc_if_icmpne:
   7.747 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.748 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.749                                     "!=", topMostLabel);
   7.750                      break;
   7.751                  case opc_if_icmplt:
   7.752 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.753 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.754                                     "<", topMostLabel);
   7.755                      break;
   7.756                  case opc_if_icmple:
   7.757 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.758 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.759                                     "<=", topMostLabel);
   7.760                      break;
   7.761                  case opc_if_icmpgt:
   7.762 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.763 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.764                                     ">", topMostLabel);
   7.765                      break;
   7.766                  case opc_if_icmpge:
   7.767 -                    i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   7.768 +                    i = generateIf(smapper, byteCodes, i, smapper.popI(), smapper.popI(),
   7.769                                     ">=", topMostLabel);
   7.770                      break;
   7.771                  case opc_goto: {
   7.772 +                    smapper.flush(out);
   7.773                      int indx = i + readShortArg(byteCodes, i);
   7.774                      goTo(out, i, indx, topMostLabel);
   7.775                      i += 2;
   7.776 @@ -974,7 +987,7 @@
   7.777                  case opc_new: {
   7.778                      int indx = readUShortArg(byteCodes, i);
   7.779                      String ci = jc.getClassName(indx);
   7.780 -                    emit(out, "var @1 = new @2;",
   7.781 +                    emit(smapper, out, "var @1 = new @2;",
   7.782                           smapper.pushA(), accessClass(mangleClassName(ci)));
   7.783                      addReference(ci);
   7.784                      i += 2;
   7.785 @@ -997,54 +1010,53 @@
   7.786                      break;
   7.787                  }
   7.788                  case opc_arraylength:
   7.789 -                    emit(out, "var @2 = @1.length;",
   7.790 -                         smapper.popA(), smapper.pushI());
   7.791 +                    smapper.replace(out, VarType.INTEGER, "(@1).length", smapper.getA(0));
   7.792                      break;
   7.793                  case opc_lastore:
   7.794 -                    emit(out, "Array.at(@3, @2, @1);",
   7.795 +                    emit(smapper, out, "Array.at(@3, @2, @1);",
   7.796                           smapper.popL(), smapper.popI(), smapper.popA());
   7.797                      break;
   7.798                  case opc_fastore:
   7.799 -                    emit(out, "Array.at(@3, @2, @1);",
   7.800 +                    emit(smapper, out, "Array.at(@3, @2, @1);",
   7.801                           smapper.popF(), smapper.popI(), smapper.popA());
   7.802                      break;
   7.803                  case opc_dastore:
   7.804 -                    emit(out, "Array.at(@3, @2, @1);",
   7.805 +                    emit(smapper, out, "Array.at(@3, @2, @1);",
   7.806                           smapper.popD(), smapper.popI(), smapper.popA());
   7.807                      break;
   7.808                  case opc_aastore:
   7.809 -                    emit(out, "Array.at(@3, @2, @1);",
   7.810 +                    emit(smapper, out, "Array.at(@3, @2, @1);",
   7.811                           smapper.popA(), smapper.popI(), smapper.popA());
   7.812                      break;
   7.813                  case opc_iastore:
   7.814                  case opc_bastore:
   7.815                  case opc_castore:
   7.816                  case opc_sastore:
   7.817 -                    emit(out, "Array.at(@3, @2, @1);",
   7.818 +                    emit(smapper, out, "Array.at(@3, @2, @1);",
   7.819                           smapper.popI(), smapper.popI(), smapper.popA());
   7.820                      break;
   7.821                  case opc_laload:
   7.822 -                    emit(out, "var @3 = Array.at(@2, @1);",
   7.823 -                         smapper.popI(), smapper.popA(), smapper.pushL());
   7.824 +                    smapper.replace(out, VarType.LONG, "Array.at(@2, @1)",
   7.825 +                         smapper.popI(), smapper.getA(0));
   7.826                      break;
   7.827                  case opc_faload:
   7.828 -                    emit(out, "var @3 = Array.at(@2, @1);",
   7.829 -                         smapper.popI(), smapper.popA(), smapper.pushF());
   7.830 +                    smapper.replace(out, VarType.FLOAT, "Array.at(@2, @1)",
   7.831 +                         smapper.popI(), smapper.getA(0));
   7.832                      break;
   7.833                  case opc_daload:
   7.834 -                    emit(out, "var @3 = Array.at(@2, @1);",
   7.835 -                         smapper.popI(), smapper.popA(), smapper.pushD());
   7.836 +                    smapper.replace(out, VarType.DOUBLE, "Array.at(@2, @1)",
   7.837 +                         smapper.popI(), smapper.getA(0));
   7.838                      break;
   7.839                  case opc_aaload:
   7.840 -                    emit(out, "var @3 = Array.at(@2, @1);",
   7.841 -                         smapper.popI(), smapper.popA(), smapper.pushA());
   7.842 +                    smapper.replace(out, VarType.REFERENCE, "Array.at(@2, @1)",
   7.843 +                         smapper.popI(), smapper.getA(0));
   7.844                      break;
   7.845                  case opc_iaload:
   7.846                  case opc_baload:
   7.847                  case opc_caload:
   7.848                  case opc_saload:
   7.849 -                    emit(out, "var @3 = Array.at(@2, @1);",
   7.850 -                         smapper.popI(), smapper.popA(), smapper.pushI());
   7.851 +                    smapper.replace(out, VarType.INTEGER, "Array.at(@2, @1)",
   7.852 +                         smapper.popI(), smapper.getA(0));
   7.853                      break;
   7.854                  case opc_pop:
   7.855                  case opc_pop2:
   7.856 @@ -1053,86 +1065,86 @@
   7.857                      break;
   7.858                  case opc_dup: {
   7.859                      final Variable v = smapper.get(0);
   7.860 -                    emit(out, "var @1 = @2;", smapper.pushT(v.getType()), v);
   7.861 +                    emit(smapper, out, "var @1 = @2;", smapper.pushT(v.getType()), v);
   7.862                      break;
   7.863                  }
   7.864                  case opc_dup2: {
   7.865                      final Variable vi1 = smapper.get(0);
   7.866  
   7.867                      if (vi1.isCategory2()) {
   7.868 -                        emit(out, "var @1 = @2;",
   7.869 +                        emit(smapper, out, "var @1 = @2;",
   7.870                               smapper.pushT(vi1.getType()), vi1);
   7.871                      } else {
   7.872                          final Variable vi2 = smapper.get(1);
   7.873 -                        emit(out, "var @1 = @2, @3 = @4;",
   7.874 +                        emit(smapper, out, "var @1 = @2, @3 = @4;",
   7.875                               smapper.pushT(vi2.getType()), vi2,
   7.876                               smapper.pushT(vi1.getType()), vi1);
   7.877                      }
   7.878                      break;
   7.879                  }
   7.880                  case opc_dup_x1: {
   7.881 -                    final Variable vi1 = smapper.pop();
   7.882 -                    final Variable vi2 = smapper.pop();
   7.883 +                    final Variable vi1 = smapper.pop(out);
   7.884 +                    final Variable vi2 = smapper.pop(out);
   7.885                      final Variable vo3 = smapper.pushT(vi1.getType());
   7.886                      final Variable vo2 = smapper.pushT(vi2.getType());
   7.887                      final Variable vo1 = smapper.pushT(vi1.getType());
   7.888  
   7.889 -                    emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.890 +                    emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.891                           vo1, vi1, vo2, vi2, vo3, vo1);
   7.892                      break;
   7.893                  }
   7.894                  case opc_dup2_x1: {
   7.895 -                    final Variable vi1 = smapper.pop();
   7.896 -                    final Variable vi2 = smapper.pop();
   7.897 +                    final Variable vi1 = smapper.pop(out);
   7.898 +                    final Variable vi2 = smapper.pop(out);
   7.899  
   7.900                      if (vi1.isCategory2()) {
   7.901                          final Variable vo3 = smapper.pushT(vi1.getType());
   7.902                          final Variable vo2 = smapper.pushT(vi2.getType());
   7.903                          final Variable vo1 = smapper.pushT(vi1.getType());
   7.904  
   7.905 -                        emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.906 +                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.907                               vo1, vi1, vo2, vi2, vo3, vo1);
   7.908                      } else {
   7.909 -                        final Variable vi3 = smapper.pop();
   7.910 +                        final Variable vi3 = smapper.pop(out);
   7.911                          final Variable vo5 = smapper.pushT(vi2.getType());
   7.912                          final Variable vo4 = smapper.pushT(vi1.getType());
   7.913                          final Variable vo3 = smapper.pushT(vi3.getType());
   7.914                          final Variable vo2 = smapper.pushT(vi2.getType());
   7.915                          final Variable vo1 = smapper.pushT(vi1.getType());
   7.916  
   7.917 -                        emit(out, "var @1 = @2, @3 = @4, @5 = @6,",
   7.918 +                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6,",
   7.919                               vo1, vi1, vo2, vi2, vo3, vi3);
   7.920 -                        emit(out, " @1 = @2, @3 = @4;",
   7.921 +                        emit(smapper, out, " @1 = @2, @3 = @4;",
   7.922                               vo4, vo1, vo5, vo2);
   7.923                      }
   7.924                      break;
   7.925                  }
   7.926                  case opc_dup_x2: {
   7.927 -                    final Variable vi1 = smapper.pop();
   7.928 -                    final Variable vi2 = smapper.pop();
   7.929 +                    final Variable vi1 = smapper.pop(out);
   7.930 +                    final Variable vi2 = smapper.pop(out);
   7.931  
   7.932                      if (vi2.isCategory2()) {
   7.933                          final Variable vo3 = smapper.pushT(vi1.getType());
   7.934                          final Variable vo2 = smapper.pushT(vi2.getType());
   7.935                          final Variable vo1 = smapper.pushT(vi1.getType());
   7.936  
   7.937 -                        emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.938 +                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.939                               vo1, vi1, vo2, vi2, vo3, vo1);
   7.940                      } else {
   7.941 -                        final Variable vi3 = smapper.pop();
   7.942 +                        final Variable vi3 = smapper.pop(out);
   7.943                          final Variable vo4 = smapper.pushT(vi1.getType());
   7.944                          final Variable vo3 = smapper.pushT(vi3.getType());
   7.945                          final Variable vo2 = smapper.pushT(vi2.getType());
   7.946                          final Variable vo1 = smapper.pushT(vi1.getType());
   7.947  
   7.948 -                        emit(out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
   7.949 +                        emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
   7.950                               vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
   7.951                      }
   7.952                      break;
   7.953                  }
   7.954                  case opc_dup2_x2: {
   7.955 -                    final Variable vi1 = smapper.pop();
   7.956 -                    final Variable vi2 = smapper.pop();
   7.957 +                    final Variable vi1 = smapper.pop(out);
   7.958 +                    final Variable vi2 = smapper.pop(out);
   7.959  
   7.960                      if (vi1.isCategory2()) {
   7.961                          if (vi2.isCategory2()) {
   7.962 @@ -1140,20 +1152,20 @@
   7.963                              final Variable vo2 = smapper.pushT(vi2.getType());
   7.964                              final Variable vo1 = smapper.pushT(vi1.getType());
   7.965  
   7.966 -                            emit(out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.967 +                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6;",
   7.968                                   vo1, vi1, vo2, vi2, vo3, vo1);
   7.969                          } else {
   7.970 -                            final Variable vi3 = smapper.pop();
   7.971 +                            final Variable vi3 = smapper.pop(out);
   7.972                              final Variable vo4 = smapper.pushT(vi1.getType());
   7.973                              final Variable vo3 = smapper.pushT(vi3.getType());
   7.974                              final Variable vo2 = smapper.pushT(vi2.getType());
   7.975                              final Variable vo1 = smapper.pushT(vi1.getType());
   7.976  
   7.977 -                            emit(out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
   7.978 +                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8;",
   7.979                                   vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
   7.980                          }
   7.981                      } else {
   7.982 -                        final Variable vi3 = smapper.pop();
   7.983 +                        final Variable vi3 = smapper.pop(out);
   7.984  
   7.985                          if (vi3.isCategory2()) {
   7.986                              final Variable vo5 = smapper.pushT(vi2.getType());
   7.987 @@ -1162,12 +1174,12 @@
   7.988                              final Variable vo2 = smapper.pushT(vi2.getType());
   7.989                              final Variable vo1 = smapper.pushT(vi1.getType());
   7.990  
   7.991 -                            emit(out, "var @1 = @2, @3 = @4, @5 = @6,",
   7.992 +                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6,",
   7.993                                   vo1, vi1, vo2, vi2, vo3, vi3);
   7.994 -                            emit(out, " @1 = @2, @3 = @4;",
   7.995 +                            emit(smapper, out, " @1 = @2, @3 = @4;",
   7.996                                   vo4, vo1, vo5, vo2);
   7.997                          } else {
   7.998 -                            final Variable vi4 = smapper.pop();
   7.999 +                            final Variable vi4 = smapper.pop(out);
  7.1000                              final Variable vo6 = smapper.pushT(vi2.getType());
  7.1001                              final Variable vo5 = smapper.pushT(vi1.getType());
  7.1002                              final Variable vo4 = smapper.pushT(vi4.getType());
  7.1003 @@ -1175,9 +1187,9 @@
  7.1004                              final Variable vo2 = smapper.pushT(vi2.getType());
  7.1005                              final Variable vo1 = smapper.pushT(vi1.getType());
  7.1006                              
  7.1007 -                            emit(out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8,",
  7.1008 +                            emit(smapper, out, "var @1 = @2, @3 = @4, @5 = @6, @7 = @8,",
  7.1009                                   vo1, vi1, vo2, vi2, vo3, vi3, vo4, vi4);
  7.1010 -                            emit(out, " @1 = @2, @3 = @4;",
  7.1011 +                            emit(smapper, out, " @1 = @2, @3 = @4;",
  7.1012                                   vo5, vo1, vo6, vo2);
  7.1013                          }
  7.1014                      }
  7.1015 @@ -1190,7 +1202,7 @@
  7.1016                      if (vi1.getType() == vi2.getType()) {
  7.1017                          final Variable tmp = smapper.pushT(vi1.getType());
  7.1018  
  7.1019 -                        emit(out, "var @1 = @2, @2 = @3, @3 = @1;",
  7.1020 +                        emit(smapper, out, "var @1 = @2, @2 = @3, @3 = @1;",
  7.1021                               tmp, vi1, vi2);
  7.1022                          smapper.pop(1);
  7.1023                      } else {
  7.1024 @@ -1201,13 +1213,13 @@
  7.1025                      break;
  7.1026                  }
  7.1027                  case opc_bipush:
  7.1028 -                    emit(out, "var @1 = @2;",
  7.1029 -                         smapper.pushI(), Integer.toString(byteCodes[++i]));
  7.1030 +                    smapper.assign(out, VarType.INTEGER, 
  7.1031 +                        "(" + Integer.toString(byteCodes[++i]) + ")");
  7.1032                      break;
  7.1033                  case opc_sipush:
  7.1034 -                    emit(out, "var @1 = @2;",
  7.1035 -                         smapper.pushI(),
  7.1036 -                         Integer.toString(readShortArg(byteCodes, i)));
  7.1037 +                    smapper.assign(out, VarType.INTEGER, 
  7.1038 +                        "(" + Integer.toString(readShortArg(byteCodes, i)) + ")"
  7.1039 +                    );
  7.1040                      i += 2;
  7.1041                      break;
  7.1042                  case opc_getfield: {
  7.1043 @@ -1216,9 +1228,9 @@
  7.1044                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  7.1045                      final String mangleClass = mangleClassName(fi[0]);
  7.1046                      final String mangleClassAccess = accessClass(mangleClass);
  7.1047 -                    emit(out, "var @2 = @4(false)._@3.call(@1);",
  7.1048 -                         smapper.popA(),
  7.1049 -                         smapper.pushT(type), fi[1], mangleClassAccess
  7.1050 +                    smapper.replace(out, type, "@3(false)._@2.call(@1)",
  7.1051 +                         smapper.getA(0),
  7.1052 +                         fi[1], mangleClassAccess
  7.1053                      );
  7.1054                      i += 2;
  7.1055                      break;
  7.1056 @@ -1229,7 +1241,7 @@
  7.1057                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  7.1058                      final String mangleClass = mangleClassName(fi[0]);
  7.1059                      final String mangleClassAccess = accessClass(mangleClass);
  7.1060 -                    emit(out, "@4(false)._@3.call(@2, @1);",
  7.1061 +                    emit(smapper, out, "@4(false)._@3.call(@2, @1);",
  7.1062                           smapper.popT(type),
  7.1063                           smapper.popA(), fi[1], 
  7.1064                           mangleClassAccess
  7.1065 @@ -1241,9 +1253,8 @@
  7.1066                      int indx = readUShortArg(byteCodes, i);
  7.1067                      String[] fi = jc.getFieldInfoName(indx);
  7.1068                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  7.1069 -                    emit(out, "var @1 = @2(false)._@3();",
  7.1070 -                         smapper.pushT(type),
  7.1071 -                         accessClass(mangleClassName(fi[0])), fi[1]);
  7.1072 +                    String ac = accessClass(mangleClassName(fi[0]));
  7.1073 +                    smapper.assign(out, type, ac + "(false)._" + fi[1] + "()");
  7.1074                      i += 2;
  7.1075                      addReference(fi[0]);
  7.1076                      break;
  7.1077 @@ -1252,7 +1263,7 @@
  7.1078                      int indx = readUShortArg(byteCodes, i);
  7.1079                      String[] fi = jc.getFieldInfoName(indx);
  7.1080                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  7.1081 -                    emit(out, "@1(false)._@2(@3);",
  7.1082 +                    emit(smapper, out, "@1(false)._@2(@3);",
  7.1083                           accessClass(mangleClassName(fi[0])), fi[1],
  7.1084                           smapper.popT(type));
  7.1085                      i += 2;
  7.1086 @@ -1272,22 +1283,22 @@
  7.1087                      break;
  7.1088                  }
  7.1089                  case opc_athrow: {
  7.1090 -                    final Variable v = smapper.popA();
  7.1091 +                    final CharSequence v = smapper.popA();
  7.1092                      smapper.clear();
  7.1093  
  7.1094 -                    emit(out, "{ var @1 = @2; throw @2; }",
  7.1095 +                    emit(smapper, out, "{ var @1 = @2; throw @2; }",
  7.1096                           smapper.pushA(), v);
  7.1097                      break;
  7.1098                  }
  7.1099  
  7.1100                  case opc_monitorenter: {
  7.1101 -                    out.append("/* monitor enter */");
  7.1102 +                    debug("/* monitor enter */");
  7.1103                      smapper.popA();
  7.1104                      break;
  7.1105                  }
  7.1106  
  7.1107                  case opc_monitorexit: {
  7.1108 -                    out.append("/* monitor exit */");
  7.1109 +                    debug("/* monitor exit */");
  7.1110                      smapper.popA();
  7.1111                      break;
  7.1112                  }
  7.1113 @@ -1298,7 +1309,7 @@
  7.1114  
  7.1115                  default: {
  7.1116                      wide = false;
  7.1117 -                    emit(out, "throw 'unknown bytecode @1';",
  7.1118 +                    emit(smapper, out, "throw 'unknown bytecode @1';",
  7.1119                           Integer.toString(c));
  7.1120                  }
  7.1121              }
  7.1122 @@ -1310,18 +1321,24 @@
  7.1123          if (previousTrap != null) {
  7.1124              generateCatch(previousTrap, byteCodes.length, topMostLabel);
  7.1125          }
  7.1126 -        out.append("\n    }\n");
  7.1127 +        if (didBranches) {
  7.1128 +            out.append("\n    }\n");
  7.1129 +        }
  7.1130          while (openBraces-- > 0) {
  7.1131              out.append('}');
  7.1132          }
  7.1133          out.append("\n};");
  7.1134      }
  7.1135  
  7.1136 -    private int generateIf(byte[] byteCodes, int i, final Variable v2, final Variable v1, final String test, int topMostLabel) throws IOException {
  7.1137 +    private int generateIf(StackMapper mapper, byte[] byteCodes, 
  7.1138 +        int i, final CharSequence v2, final CharSequence v1, 
  7.1139 +        final String test, int topMostLabel
  7.1140 +    ) throws IOException {
  7.1141 +        mapper.flush(out);
  7.1142          int indx = i + readShortArg(byteCodes, i);
  7.1143 -        out.append("if (").append(v1)
  7.1144 -           .append(' ').append(test).append(' ')
  7.1145 -           .append(v2).append(") ");
  7.1146 +        out.append("if ((").append(v1)
  7.1147 +           .append(") ").append(test).append(" (")
  7.1148 +           .append(v2).append(")) ");
  7.1149          goTo(out, i, indx, topMostLabel);
  7.1150          return i + 2;
  7.1151      }
  7.1152 @@ -1502,10 +1519,10 @@
  7.1153          String mn = findMethodName(mi, cnt, returnType);
  7.1154  
  7.1155          final int numArguments = isStatic ? cnt.length() : cnt.length() + 1;
  7.1156 -        final Variable[] vars = new Variable[numArguments];
  7.1157 +        final CharSequence[] vars = new CharSequence[numArguments];
  7.1158  
  7.1159          for (int j = numArguments - 1; j >= 0; --j) {
  7.1160 -            vars[j] = mapper.pop();
  7.1161 +            vars[j] = mapper.popValue();
  7.1162          }
  7.1163  
  7.1164          if (returnType[0] != 'V') {
  7.1165 @@ -1547,10 +1564,10 @@
  7.1166          String mn = findMethodName(mi, cnt, returnType);
  7.1167  
  7.1168          final int numArguments = cnt.length() + 1;
  7.1169 -        final Variable[] vars = new Variable[numArguments];
  7.1170 +        final CharSequence[] vars = new CharSequence[numArguments];
  7.1171  
  7.1172          for (int j = numArguments - 1; j >= 0; --j) {
  7.1173 -            vars[j] = mapper.pop();
  7.1174 +            vars[j] = mapper.popValue();
  7.1175          }
  7.1176  
  7.1177          if (returnType[0] != 'V') {
  7.1178 @@ -1598,7 +1615,7 @@
  7.1179          String s = jc.stringValue(entryIndex, classRef);
  7.1180          if (classRef[0] != null) {
  7.1181              if (classRef[0].startsWith("[")) {
  7.1182 -                s = accessClass("java_lang_Class") + "(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('" + classRef[0] + "');";
  7.1183 +                s = accessClass("java_lang_Class") + "(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('" + classRef[0] + "')";
  7.1184              } else {
  7.1185                  addReference(classRef[0]);
  7.1186                  s = accessClass(mangleClassName(s)) + "(false).constructor.$class";
  7.1187 @@ -1935,7 +1952,22 @@
  7.1188          return ",";
  7.1189      }
  7.1190  
  7.1191 -    private static void emit(final Appendable out,
  7.1192 +    final void emitNoFlush(
  7.1193 +        StackMapper sm, 
  7.1194 +        final Appendable out, 
  7.1195 +        final String format, final CharSequence... params
  7.1196 +    ) throws IOException {
  7.1197 +        emitImpl(out, format, params);
  7.1198 +    }
  7.1199 +    final void emit(
  7.1200 +        StackMapper sm, 
  7.1201 +        final Appendable out, 
  7.1202 +        final String format, final CharSequence... params
  7.1203 +    ) throws IOException {
  7.1204 +        sm.flush(out);
  7.1205 +        emitImpl(out, format, params);
  7.1206 +    }
  7.1207 +    static void emitImpl(final Appendable out,
  7.1208                               final String format,
  7.1209                               final CharSequence... params) throws IOException {
  7.1210          final int length = format.length();
  7.1211 @@ -2001,10 +2033,13 @@
  7.1212      }
  7.1213  
  7.1214      private static void emitIf(
  7.1215 -        Appendable out, String pattern, Variable param, 
  7.1216 +        StackMapper sm, 
  7.1217 +        Appendable out, String pattern, 
  7.1218 +        CharSequence param, 
  7.1219          int current, int to, int canBack
  7.1220      ) throws IOException {
  7.1221 -        emit(out, pattern, param);
  7.1222 +        sm.flush(out);
  7.1223 +        emitImpl(out, pattern, param);
  7.1224          goTo(out, current, to, canBack);
  7.1225      }
  7.1226  
  7.1227 @@ -2021,7 +2056,7 @@
  7.1228              case 11: jvmType = "[J"; break;
  7.1229              default: throw new IllegalStateException("Array type: " + atype);
  7.1230          }
  7.1231 -        emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
  7.1232 +        emit(smapper, out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
  7.1233               smapper.popI(), smapper.pushA(), jvmType);
  7.1234      }
  7.1235  
  7.1236 @@ -2032,7 +2067,7 @@
  7.1237          } else {
  7.1238              typeName = "[L" + typeName + ";";
  7.1239          }
  7.1240 -        emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
  7.1241 +        emit(smapper, out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
  7.1242               smapper.popI(), smapper.pushA(), typeName);
  7.1243      }
  7.1244  
  7.1245 @@ -2048,7 +2083,7 @@
  7.1246              dims.insert(1, smapper.popI());
  7.1247          }
  7.1248          dims.append(']');
  7.1249 -        emit(out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
  7.1250 +        emit(smapper, out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
  7.1251               dims.toString(), smapper.pushA(), typeName);
  7.1252          return i;
  7.1253      }
  7.1254 @@ -2061,7 +2096,9 @@
  7.1255          table += 4;
  7.1256          int high = readInt4(byteCodes, table);
  7.1257          table += 4;
  7.1258 -        out.append("switch (").append(smapper.popI()).append(") {\n");
  7.1259 +        final CharSequence swVar = smapper.popValue();
  7.1260 +        smapper.flush(out);
  7.1261 +        out.append("switch (").append(swVar).append(") {\n");
  7.1262          while (low <= high) {
  7.1263              int offset = i + readInt4(byteCodes, table);
  7.1264              table += 4;
  7.1265 @@ -2081,7 +2118,9 @@
  7.1266          table += 4;
  7.1267          int n = readInt4(byteCodes, table);
  7.1268          table += 4;
  7.1269 -        out.append("switch (").append(smapper.popI()).append(") {\n");
  7.1270 +        final CharSequence swVar = smapper.popValue();
  7.1271 +        smapper.flush(out);
  7.1272 +        out.append("switch (").append(swVar).append(") {\n");
  7.1273          while (n-- > 0) {
  7.1274              int cnstnt = readInt4(byteCodes, table);
  7.1275              table += 4;
  7.1276 @@ -2099,11 +2138,11 @@
  7.1277      private void generateInstanceOf(int indx, final StackMapper smapper) throws IOException {
  7.1278          final String type = jc.getClassName(indx);
  7.1279          if (!type.startsWith("[")) {
  7.1280 -            emit(out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
  7.1281 +            emit(smapper, out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
  7.1282                   smapper.popA(), smapper.pushI(),
  7.1283                   type.replace('/', '_'));
  7.1284          } else {
  7.1285 -            emit(out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
  7.1286 +            emit(smapper, out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
  7.1287                  smapper.popA(), smapper.pushI(),
  7.1288                  type
  7.1289              );
  7.1290 @@ -2113,12 +2152,12 @@
  7.1291      private void generateCheckcast(int indx, final StackMapper smapper) throws IOException {
  7.1292          final String type = jc.getClassName(indx);
  7.1293          if (!type.startsWith("[")) {
  7.1294 -            emit(out,
  7.1295 +            emitNoFlush(smapper, out,
  7.1296                   "if (@1 !== null && !@1.$instOf_@2) throw vm.java_lang_ClassCastException(true);",
  7.1297 -                 smapper.getA(0), type.replace('/', '_'));
  7.1298 +                 smapper.getT(0, VarType.REFERENCE, false), type.replace('/', '_'));
  7.1299          } else {
  7.1300 -            emit(out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
  7.1301 -                 smapper.getA(0), type
  7.1302 +            emitNoFlush(smapper, out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
  7.1303 +                 smapper.getT(0, VarType.REFERENCE, false), type
  7.1304              );
  7.1305          }
  7.1306      }
     8.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java	Sun Feb 16 20:06:03 2014 +0100
     8.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java	Wed Feb 19 08:10:04 2014 +0100
     8.3 @@ -254,6 +254,7 @@
     8.4              "shr64",
     8.5              "ushr64",
     8.6              "compare64",
     8.7 +            "compare",
     8.8              "neg64",
     8.9              "div32",
    8.10              "mod32",
     9.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java	Sun Feb 16 20:06:03 2014 +0100
     9.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java	Wed Feb 19 08:10:04 2014 +0100
     9.3 @@ -17,24 +17,21 @@
     9.4   */
     9.5  package org.apidesign.vm4brwsr;
     9.6  
     9.7 +import java.io.IOException;
     9.8  import org.apidesign.vm4brwsr.ByteCodeParser.TypeArray;
     9.9  
    9.10  final class StackMapper {
    9.11      private final TypeArray stackTypeIndexPairs;
    9.12 -    private int[] typeCounters;
    9.13 -    private int[] typeMaxCounters;
    9.14 +    private final StringArray stackValues;
    9.15  
    9.16      public StackMapper() {
    9.17          stackTypeIndexPairs = new TypeArray();
    9.18 -        typeCounters = new int[VarType.LAST + 1];
    9.19 -        typeMaxCounters = new int[VarType.LAST + 1];
    9.20 +        stackValues = new StringArray();
    9.21      }
    9.22  
    9.23      public void clear() {
    9.24 -        for (int type = 0; type <= VarType.LAST; ++type) {
    9.25 -            typeCounters[type] = 0;
    9.26 -        }
    9.27          stackTypeIndexPairs.clear();
    9.28 +        stackValues.clear();
    9.29      }
    9.30  
    9.31      public void syncWithFrameStack(final TypeArray frameStack) {
    9.32 @@ -70,33 +67,66 @@
    9.33          return getVariable(pushTypeImpl(type));
    9.34      }
    9.35  
    9.36 -    public Variable popI() {
    9.37 +    void assign(Appendable out, int varType, CharSequence s) throws IOException {
    9.38 +        pushTypeAndValue(varType, s);
    9.39 +    }
    9.40 +
    9.41 +    void replace(Appendable out, int varType, String format, CharSequence... arr) 
    9.42 +    throws IOException {
    9.43 +        StringBuilder sb = new StringBuilder();
    9.44 +        ByteCodeToJavaScript.emitImpl(sb, format, arr);
    9.45 +        String[] values = stackValues.toArray();
    9.46 +        final int last = stackTypeIndexPairs.getSize() - 1;
    9.47 +        values[last] = sb.toString();
    9.48 +        final int value = (last << 8) | (varType & 0xff);
    9.49 +        stackTypeIndexPairs.set(last, value);
    9.50 +    }
    9.51 +    
    9.52 +    void flush(Appendable out) throws IOException {
    9.53 +        int count = stackTypeIndexPairs.getSize();
    9.54 +        for (int i = 0; i < count; i++) {
    9.55 +            String val = stackValues.getAndClear(i, true);
    9.56 +            if (val == null) {
    9.57 +                continue;
    9.58 +            }
    9.59 +            CharSequence var = getVariable(stackTypeIndexPairs.get(i));
    9.60 +            ByteCodeToJavaScript.emitImpl(out, "var @1 = @2;", var, val);
    9.61 +        }
    9.62 +    }
    9.63 +    
    9.64 +    public CharSequence popI() {
    9.65          return popT(VarType.INTEGER);
    9.66      }
    9.67  
    9.68 -    public Variable popL() {
    9.69 +    public CharSequence popL() {
    9.70          return popT(VarType.LONG);
    9.71      }
    9.72  
    9.73 -    public Variable popF() {
    9.74 +    public CharSequence popF() {
    9.75          return popT(VarType.FLOAT);
    9.76      }
    9.77  
    9.78 -    public Variable popD() {
    9.79 +    public CharSequence popD() {
    9.80          return popT(VarType.DOUBLE);
    9.81      }
    9.82  
    9.83 -    public Variable popA() {
    9.84 +    public CharSequence popA() {
    9.85          return popT(VarType.REFERENCE);
    9.86      }
    9.87  
    9.88 -    public Variable popT(final int type) {
    9.89 -        final Variable variable = getT(0, type);
    9.90 +    public CharSequence popT(final int type) {
    9.91 +        final CharSequence variable = getT(0, type);
    9.92          popImpl(1);
    9.93          return variable;
    9.94      }
    9.95  
    9.96 -    public Variable pop() {
    9.97 +    public CharSequence popValue() {
    9.98 +        final CharSequence variable = getT(0, -1);
    9.99 +        popImpl(1);
   9.100 +        return variable;
   9.101 +    }
   9.102 +    public Variable pop(Appendable out) throws IOException {
   9.103 +        flush(out);
   9.104          final Variable variable = get(0);
   9.105          popImpl(1);
   9.106          return variable;
   9.107 @@ -110,37 +140,44 @@
   9.108          popImpl(count);
   9.109      }
   9.110  
   9.111 -    public Variable getI(final int indexFromTop) {
   9.112 +    public CharSequence getI(final int indexFromTop) {
   9.113          return getT(indexFromTop, VarType.INTEGER);
   9.114      }
   9.115  
   9.116 -    public Variable getL(final int indexFromTop) {
   9.117 +    public CharSequence getL(final int indexFromTop) {
   9.118          return getT(indexFromTop, VarType.LONG);
   9.119      }
   9.120  
   9.121 -    public Variable getF(final int indexFromTop) {
   9.122 +    public CharSequence getF(final int indexFromTop) {
   9.123          return getT(indexFromTop, VarType.FLOAT);
   9.124      }
   9.125  
   9.126 -    public Variable getD(final int indexFromTop) {
   9.127 +    public CharSequence getD(final int indexFromTop) {
   9.128          return getT(indexFromTop, VarType.DOUBLE);
   9.129      }
   9.130  
   9.131 -    public Variable getA(final int indexFromTop) {
   9.132 +    public CharSequence getA(final int indexFromTop) {
   9.133          return getT(indexFromTop, VarType.REFERENCE);
   9.134      }
   9.135  
   9.136 -    public Variable getT(final int indexFromTop, final int type) {
   9.137 +    public CharSequence getT(final int indexFromTop, final int type) {
   9.138 +        return getT(indexFromTop, type, true);
   9.139 +    }
   9.140 +    public CharSequence getT(final int indexFromTop, final int type, boolean clear) {
   9.141          final int stackSize = stackTypeIndexPairs.getSize();
   9.142          if (indexFromTop >= stackSize) {
   9.143              throw new IllegalStateException("Stack underflow");
   9.144          }
   9.145          final int stackValue =
   9.146                  stackTypeIndexPairs.get(stackSize - indexFromTop - 1);
   9.147 -        if ((stackValue & 0xff) != type) {
   9.148 +        if (type != -1 && (stackValue & 0xff) != type) {
   9.149              throw new IllegalStateException("Type mismatch");
   9.150          }
   9.151 -
   9.152 +        String value =
   9.153 +            stackValues.getAndClear(stackSize - indexFromTop - 1, clear);
   9.154 +        if (value != null) {
   9.155 +            return value;
   9.156 +        }
   9.157          return getVariable(stackValue);
   9.158      }
   9.159  
   9.160 @@ -156,35 +193,36 @@
   9.161      }
   9.162  
   9.163      private int pushTypeImpl(final int type) {
   9.164 -        final int count = typeCounters[type];
   9.165 +        final int count = stackTypeIndexPairs.getSize();
   9.166          final int value = (count << 8) | (type & 0xff);
   9.167 -        incCounter(type);
   9.168          stackTypeIndexPairs.add(value);
   9.169 +        
   9.170 +        addStackValue(count, null);
   9.171 +        return value;
   9.172 +    }
   9.173  
   9.174 -        return value;
   9.175 +    private void pushTypeAndValue(final int type, CharSequence v) {
   9.176 +        final int count = stackTypeIndexPairs.getSize();
   9.177 +        final int value = (count << 8) | (type & 0xff);
   9.178 +        stackTypeIndexPairs.add(value);
   9.179 +        final String val = v.toString();
   9.180 +        addStackValue(count, val);
   9.181 +    }
   9.182 +
   9.183 +    private void addStackValue(int at, final String val) {
   9.184 +        final String[] arr = stackValues.toArray();
   9.185 +        if (arr.length > at) {
   9.186 +            arr[at] = val;
   9.187 +        } else {
   9.188 +            stackValues.add(val);
   9.189 +        }
   9.190      }
   9.191  
   9.192      private void popImpl(final int count) {
   9.193          final int stackSize = stackTypeIndexPairs.getSize();
   9.194 -        for (int i = stackSize - count; i < stackSize; ++i) {
   9.195 -            final int value = stackTypeIndexPairs.get(i);
   9.196 -            decCounter(value & 0xff);
   9.197 -        }
   9.198 -
   9.199          stackTypeIndexPairs.setSize(stackSize - count);
   9.200      }
   9.201  
   9.202 -    private void incCounter(final int type) {
   9.203 -        final int newValue = ++typeCounters[type];
   9.204 -        if (typeMaxCounters[type] < newValue) {
   9.205 -            typeMaxCounters[type] = newValue;
   9.206 -        }
   9.207 -    }
   9.208 -
   9.209 -    private void decCounter(final int type) {
   9.210 -        --typeCounters[type];
   9.211 -    }
   9.212 -
   9.213      public Variable getVariable(final int typeAndIndex) {
   9.214          final int type = typeAndIndex & 0xff;
   9.215          final int index = typeAndIndex >> 8;
    10.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Sun Feb 16 20:06:03 2014 +0100
    10.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Wed Feb 19 08:10:04 2014 +0100
    10.3 @@ -105,11 +105,23 @@
    10.4      }
    10.5  
    10.6      int indexOf(String ic) {
    10.7 -        for (int i = 0; i < arr.length; i++) {
    10.8 +        if (arr != null) for (int i = 0; i < arr.length; i++) {
    10.9              if (ic.equals(arr[i])) {
   10.10                  return i;
   10.11              }
   10.12          }
   10.13          return -1;
   10.14      }
   10.15 +
   10.16 +    String getAndClear(int count, boolean clear) {
   10.17 +        String s = arr[count];
   10.18 +        if (clear) {
   10.19 +            arr[count] = null;
   10.20 +        }
   10.21 +        return s;
   10.22 +    }
   10.23 +
   10.24 +    void clear() {
   10.25 +        arr = null;
   10.26 +    }
   10.27  }
    11.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Sun Feb 16 20:06:03 2014 +0100
    11.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Wed Feb 19 08:10:04 2014 +0100
    11.3 @@ -137,4 +137,8 @@
    11.4      
    11.5      @JavaScriptBody(args = { "instance" }, body = "return instance.getByte__B();")
    11.6      private static native int jsgetbytes(Instance instance);
    11.7 +
    11.8 +    int sum(int i, int i0) {
    11.9 +        return i + i0;
   11.10 +    }
   11.11  }
    12.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceSub.java	Sun Feb 16 20:06:03 2014 +0100
    12.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceSub.java	Wed Feb 19 08:10:04 2014 +0100
    12.3 @@ -31,7 +31,7 @@
    12.4      
    12.5      @Override
    12.6      public void setByte(byte b) {
    12.7 -        super.setByte((byte) (b + 1));
    12.8 +        super.setByte((byte) (b + StaticMethod.MISSING_CONSTANT));
    12.9      }
   12.10      
   12.11      public static double recallDbl() {
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/NoStringCnstntsTest.java	Wed Feb 19 08:10:04 2014 +0100
    13.3 @@ -0,0 +1,62 @@
    13.4 +/**
    13.5 + * Back 2 Browser Bytecode Translator
    13.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    13.7 + *
    13.8 + * This program is free software: you can redistribute it and/or modify
    13.9 + * it under the terms of the GNU General Public License as published by
   13.10 + * the Free Software Foundation, version 2 of the License.
   13.11 + *
   13.12 + * This program is distributed in the hope that it will be useful,
   13.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.15 + * GNU General Public License for more details.
   13.16 + *
   13.17 + * You should have received a copy of the GNU General Public License
   13.18 + * along with this program. Look for COPYING file in the top folder.
   13.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   13.20 + */
   13.21 +
   13.22 +package org.apidesign.vm4brwsr;
   13.23 +
   13.24 +import java.io.IOException;
   13.25 +import java.io.InputStream;
   13.26 +import static org.testng.Assert.assertEquals;
   13.27 +import org.testng.annotations.AfterClass;
   13.28 +import org.testng.annotations.BeforeClass;
   13.29 +import org.testng.annotations.Test;
   13.30 +
   13.31 +/**
   13.32 + *
   13.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   13.34 + */
   13.35 +public class NoStringCnstntsTest {
   13.36 +    private static String code;
   13.37 +
   13.38 +    
   13.39 +    @Test public void dontGeneratePrimitiveFinalConstants() {
   13.40 +        assertEquals(code.indexOf("HELLO"), -1, "MISSING_CONSTANT field should not be generated");
   13.41 +    }
   13.42 +    
   13.43 +    @BeforeClass 
   13.44 +    public static void compileTheCode() throws Exception {
   13.45 +        final String res = "org/apidesign/vm4brwsr/StringSample";
   13.46 +        StringBuilder sb = new StringBuilder();
   13.47 +        class JustStaticMethod implements Bck2Brwsr.Resources {
   13.48 +            @Override
   13.49 +            public InputStream get(String resource) throws IOException {
   13.50 +                final String cn = res + ".class";
   13.51 +                if (resource.equals(cn)) {
   13.52 +                    return getClass().getClassLoader().getResourceAsStream(cn);
   13.53 +                }
   13.54 +                return null;
   13.55 +            }
   13.56 +        }
   13.57 +        Bck2Brwsr.generate(sb, new JustStaticMethod(), res);
   13.58 +        code = sb.toString();
   13.59 +    }
   13.60 +    @AfterClass
   13.61 +    public static void releaseTheCode() {
   13.62 +        code = null;
   13.63 +    }
   13.64 +    
   13.65 +}
    14.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Sun Feb 16 20:06:03 2014 +0100
    14.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Wed Feb 19 08:10:04 2014 +0100
    14.3 @@ -117,6 +117,12 @@
    14.4          double f = 3.0;
    14.5          assertExec("Should be the same", Numbers.class, "deserDouble__D", f);
    14.6      }
    14.7 +    
    14.8 +    @Test public void bytesToLong() throws Exception {
    14.9 +        long exp = Numbers.bytesToLong((byte)30, (byte)20, 32);
   14.10 +        assertExec("Should be the same", Numbers.class, "bytesToLong__JBBI", 
   14.11 +            Double.valueOf(exp), 30, 20, 32);
   14.12 +    }
   14.13      /*
   14.14      @Test public void serDouble() throws IOException {
   14.15          double f = 3.0;
    15.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java	Sun Feb 16 20:06:03 2014 +0100
    15.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java	Wed Feb 19 08:10:04 2014 +0100
    15.3 @@ -64,6 +64,10 @@
    15.4          DataInputStream dis = new DataInputStream(is);
    15.5          return dis.readInt();
    15.6      }
    15.7 +    static long bytesToLong(byte b1, byte b2, int shift) {
    15.8 +        return (((long)b1 << 56) +
    15.9 +                ((long)b2 & 255) << 48) >> shift;
   15.10 +    }
   15.11  
   15.12      static String intToString() {
   15.13          return new Integer(5).toString().toString();
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java	Wed Feb 19 08:10:04 2014 +0100
    16.3 @@ -0,0 +1,96 @@
    16.4 +/**
    16.5 + * Back 2 Browser Bytecode Translator
    16.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    16.7 + *
    16.8 + * This program is free software: you can redistribute it and/or modify
    16.9 + * it under the terms of the GNU General Public License as published by
   16.10 + * the Free Software Foundation, version 2 of the License.
   16.11 + *
   16.12 + * This program is distributed in the hope that it will be useful,
   16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 + * GNU General Public License for more details.
   16.16 + *
   16.17 + * You should have received a copy of the GNU General Public License
   16.18 + * along with this program. Look for COPYING file in the top folder.
   16.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   16.20 + */
   16.21 +/*
   16.22 + * To change this license header, choose License Headers in Project Properties.
   16.23 + * To change this template file, choose Tools | Templates
   16.24 + * and open the template in the editor.
   16.25 + */
   16.26 +
   16.27 +package org.apidesign.vm4brwsr;
   16.28 +
   16.29 +import java.io.IOException;
   16.30 +import java.io.InputStream;
   16.31 +import static org.testng.Assert.assertEquals;
   16.32 +import static org.testng.Assert.assertTrue;
   16.33 +import org.testng.annotations.AfterClass;
   16.34 +import org.testng.annotations.BeforeClass;
   16.35 +import org.testng.annotations.Test;
   16.36 +
   16.37 +/**
   16.38 + *
   16.39 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   16.40 + */
   16.41 +public class SizeOfAMethodTest {
   16.42 +    private static String code;
   16.43 +
   16.44 +    @Test public void sumXYShouldBeSmall() {
   16.45 +        String s = code;
   16.46 +        int beg = s.indexOf("c.sum__III");
   16.47 +        int end = s.indexOf("c.sum__III.access");
   16.48 +        
   16.49 +        assertTrue(beg > 0, "Found sum method in " + code);
   16.50 +        assertTrue(beg < end, "Found end of sum method in " + code);
   16.51 +        
   16.52 +        String method = s.substring(beg, end);
   16.53 +        
   16.54 +        
   16.55 +        assertEquals(method.indexOf("st"), -1, "There should be no stack operations:\n" + method);
   16.56 +    }
   16.57 +
   16.58 +    @Test public void emptyConstructorRequiresNoStack() {
   16.59 +        String s = code;
   16.60 +        int beg = s.indexOf("CLS.cons__V");
   16.61 +        int end = s.indexOf("CLS.cons__V.access");
   16.62 +        
   16.63 +        assertTrue(beg > 0, "Found constructor in " + code);
   16.64 +        assertTrue(beg < end, "Found end of constructor in " + code);
   16.65 +        
   16.66 +        String method = s.substring(beg, end);
   16.67 +        method = method.replace("constructor", "CNSTR");
   16.68 +        
   16.69 +        assertEquals(method.indexOf("st"), -1, "There should be no stack operations:\n" + method);
   16.70 +        assertEquals(method.indexOf("for"), -1, "There should be no for blocks:\n" + method);
   16.71 +    }
   16.72 +    
   16.73 +    @Test public void dontGeneratePrimitiveFinalConstants() {
   16.74 +        assertEquals(code.indexOf("MISSING_CONSTANT"), -1, "MISSING_CONSTANT field should not be generated");
   16.75 +    }
   16.76 +    
   16.77 +    @BeforeClass 
   16.78 +    public static void compileTheCode() throws Exception {
   16.79 +        final String res = "org/apidesign/vm4brwsr/StaticMethod";
   16.80 +        StringBuilder sb = new StringBuilder();
   16.81 +        class JustStaticMethod implements Bck2Brwsr.Resources {
   16.82 +            @Override
   16.83 +            public InputStream get(String resource) throws IOException {
   16.84 +                final String cn = res + ".class";
   16.85 +                if (resource.equals(cn)) {
   16.86 +                    return getClass().getClassLoader().getResourceAsStream(cn);
   16.87 +                }
   16.88 +                return null;
   16.89 +            }
   16.90 +        }
   16.91 +        Bck2Brwsr.generate(sb, new JustStaticMethod(), res);
   16.92 +        code = sb.toString();
   16.93 +    }
   16.94 +    @AfterClass
   16.95 +    public static void releaseTheCode() {
   16.96 +        code = null;
   16.97 +    }
   16.98 +    
   16.99 +}
    17.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Sun Feb 16 20:06:03 2014 +0100
    17.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Wed Feb 19 08:10:04 2014 +0100
    17.3 @@ -24,6 +24,7 @@
    17.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
    17.5   */
    17.6  public class StaticMethod {
    17.7 +    public static final int MISSING_CONSTANT = 1;
    17.8      private static int cnt;
    17.9      private static Object NULL;
   17.10  
   17.11 @@ -82,7 +83,7 @@
   17.12          if (n <= 1) {
   17.13              return 1;
   17.14          } else {
   17.15 -            return n * factRec(n - 1);
   17.16 +            return n * factRec(n - MISSING_CONSTANT);
   17.17          }
   17.18      }
   17.19      public static long factIter(int n) {
   17.20 @@ -99,6 +100,10 @@
   17.21          return cnt;
   17.22      }
   17.23      
   17.24 +    public static int helloWorldLength(String x) {
   17.25 +        return (StringSample.HELLO + x).length();
   17.26 +    }
   17.27 +    
   17.28      @JavaScriptBody(
   17.29          args={"i","j"}, body="\n\r\treturn (i + j).toString();"
   17.30      )
   17.31 @@ -128,6 +133,62 @@
   17.32          }
   17.33      }
   17.34      
   17.35 +    public static int castString(Object o) {
   17.36 +        return ((String)o).length();
   17.37 +    }
   17.38 +    
   17.39 +    public static int initInflater(int w, boolean nowrap) {
   17.40 +        Instance i = new Instance(w, 0.0);
   17.41 +        return i.sum(nowrap?-w:w, 1);
   17.42 +    }
   17.43 +    
   17.44 +    public static String toStringArr() {
   17.45 +        class N implements Next {
   17.46 +            int idx = 0;
   17.47 +            
   17.48 +            @Override
   17.49 +            public boolean hasNext() {
   17.50 +                return idx < 5;
   17.51 +            }
   17.52 +
   17.53 +            @Override
   17.54 +            public String next() {
   17.55 +                switch (idx++) {
   17.56 +                    case 0: return "Zero";
   17.57 +                    case 1: return "One";
   17.58 +                    case 2: return "Two";
   17.59 +                    case 3: return "Three";
   17.60 +                    case 4: return "Four";
   17.61 +                }
   17.62 +                throw new IllegalStateException();
   17.63 +            }
   17.64 +        }
   17.65 +        return toString(null, new N()).toString();
   17.66 +    }
   17.67 +    
   17.68 +    static String toString(Object thiz, Next it) {
   17.69 +        if (!it.hasNext()) {
   17.70 +            return "[]";
   17.71 +        }
   17.72 +
   17.73 +        StringBuilder sb = new StringBuilder();
   17.74 +        sb.append('[');
   17.75 +        for (;;) {
   17.76 +            String e = it.next();
   17.77 +            sb.append(e == thiz ? "(this Collection)" : e);
   17.78 +            if (!it.hasNext()) {
   17.79 +                return sb.append(']').toString();
   17.80 +            }
   17.81 +            sb.append(',').append(' ');
   17.82 +        }
   17.83 +    }
   17.84 +    
   17.85 +    static interface Next {
   17.86 +        boolean hasNext();
   17.87 +        String next();
   17.88 +    }
   17.89 +    
   17.90 +    
   17.91      static {
   17.92          // check order of initializers
   17.93          StaticUse.NON_NULL.equals(new Object());
    18.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Sun Feb 16 20:06:03 2014 +0100
    18.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Wed Feb 19 08:10:04 2014 +0100
    18.3 @@ -36,6 +36,15 @@
    18.4          );
    18.5      }
    18.6  
    18.7 +    @Test public void cast() throws Exception {
    18.8 +        assertExec(
    18.9 +            "Length is four", 
   18.10 +            StaticMethod.class, "castString__ILjava_lang_Object_2", 
   18.11 +            Double.valueOf(4), 
   18.12 +            "Ahoj"
   18.13 +        );
   18.14 +    }
   18.15 +
   18.16      @Test public void checkReallyInitializedValues() throws Exception {
   18.17          assertExec(
   18.18              "Return true", 
   18.19 @@ -161,6 +170,25 @@
   18.20              3, 3.75
   18.21          );
   18.22      }
   18.23 +  
   18.24 +    @Test public void inflaterInit() throws Exception {
   18.25 +        assertExec(
   18.26 +            "Down and minus",
   18.27 +            StaticMethod.class, "initInflater__IIZ",
   18.28 +            Double.valueOf(-9),
   18.29 +            10, true
   18.30 +        );
   18.31 +    }
   18.32 +
   18.33 +    @Test public void inflaterInitNoNeg() throws Exception {
   18.34 +        assertExec(
   18.35 +            "One up",
   18.36 +            StaticMethod.class, "initInflater__IIZ",
   18.37 +            Double.valueOf(11),
   18.38 +            10, false
   18.39 +        );
   18.40 +    }
   18.41 +    
   18.42      @Test public void mixedMethodFourParams() throws Exception {
   18.43          assertExec(
   18.44              "Should be two",
   18.45 @@ -196,6 +224,15 @@
   18.46          );
   18.47      }
   18.48      
   18.49 +    @Test public void collectionToString() throws Exception {
   18.50 +        String exp = StaticMethod.toStringArr();
   18.51 +        assertExec(
   18.52 +            "0 to 4",
   18.53 +            StaticMethod.class, "toStringArr__Ljava_lang_String_2",
   18.54 +            exp
   18.55 +        );
   18.56 +    }
   18.57 +    
   18.58      @Test public void or() throws Exception {
   18.59          assertExec(
   18.60              "Or will be 7",
   18.61 @@ -322,6 +359,13 @@
   18.62          );
   18.63      }
   18.64      
   18.65 +    @Test public void stringConstantIsCopied() throws Exception {
   18.66 +        assertExec("String constants are copied between class pools",
   18.67 +            StaticMethod.class, "helloWorldLength__ILjava_lang_String_2", 
   18.68 +            17, "Jardo"
   18.69 +        );
   18.70 +    }
   18.71 +    
   18.72      private static TestVM code;
   18.73      
   18.74      @BeforeClass 
    19.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Sun Feb 16 20:06:03 2014 +0100
    19.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Wed Feb 19 08:10:04 2014 +0100
    19.3 @@ -164,7 +164,10 @@
    19.4              return ex.toString();
    19.5          }
    19.6      }
    19.7 -    
    19.8 +
    19.9 +    final CharSequence codeSeq() {
   19.10 +        return codeSeq;
   19.11 +    }
   19.12      
   19.13      private static class EmulationResources implements Bck2Brwsr.Resources {
   19.14          @Override
    20.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java	Sun Feb 16 20:06:03 2014 +0100
    20.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java	Wed Feb 19 08:10:04 2014 +0100
    20.3 @@ -79,7 +79,7 @@
    20.4                  }
    20.5              }
    20.6              w.append("\n];\n");
    20.7 -            w.append(code.toString());
    20.8 +            w.append(code.codeSeq());
    20.9              w.close();
   20.10              throw new Exception(ex.getMessage() + " file: " + f, ex);
   20.11          }