Jump instructions need to use signed and constant pool referencing instructions unsigned short. Also getting ready for reading signed short composed from (improperly) two unsigned bytes.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 20 Mar 2013 21:24:36 +0100
changeset 8648ece59d31fcf
parent 862 467ae5eb67f0
child 865 03fe918c4684
Jump instructions need to use signed and constant pool referencing instructions unsigned short. Also getting ready for reading signed short composed from (improperly) two unsigned bytes.
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Mar 20 14:01:43 2013 +0100
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Mar 20 21:24:36 2013 +0100
     1.3 @@ -782,7 +782,7 @@
     1.4                  }
     1.5                  case opc_ldc_w:
     1.6                  case opc_ldc2_w: {
     1.7 -                    int indx = readIntArg(byteCodes, i);
     1.8 +                    int indx = readUShortArg(byteCodes, i);
     1.9                      i += 2;
    1.10                      String v = encodeConstant(indx);
    1.11                      int type = VarType.fromConstantType(jc.getTag(indx));
    1.12 @@ -824,56 +824,56 @@
    1.13                                     "==", topMostLabel);
    1.14                      break;
    1.15                  case opc_ifeq: {
    1.16 -                    int indx = i + readIntArg(byteCodes, i);
    1.17 +                    int indx = i + readShortArg(byteCodes, i);
    1.18                      emitIf(out, "if (@1 == 0) ",
    1.19                           smapper.popI(), i, indx, topMostLabel);
    1.20                      i += 2;
    1.21                      break;
    1.22                  }
    1.23                  case opc_ifne: {
    1.24 -                    int indx = i + readIntArg(byteCodes, i);
    1.25 +                    int indx = i + readShortArg(byteCodes, i);
    1.26                      emitIf(out, "if (@1 != 0) ",
    1.27                           smapper.popI(), i, indx, topMostLabel);
    1.28                      i += 2;
    1.29                      break;
    1.30                  }
    1.31                  case opc_iflt: {
    1.32 -                    int indx = i + readIntArg(byteCodes, i);
    1.33 +                    int indx = i + readShortArg(byteCodes, i);
    1.34                      emitIf(out, "if (@1 < 0) ",
    1.35                           smapper.popI(), i, indx, topMostLabel);
    1.36                      i += 2;
    1.37                      break;
    1.38                  }
    1.39                  case opc_ifle: {
    1.40 -                    int indx = i + readIntArg(byteCodes, i);
    1.41 +                    int indx = i + readShortArg(byteCodes, i);
    1.42                      emitIf(out, "if (@1 <= 0) ",
    1.43                           smapper.popI(), i, indx, topMostLabel);
    1.44                      i += 2;
    1.45                      break;
    1.46                  }
    1.47                  case opc_ifgt: {
    1.48 -                    int indx = i + readIntArg(byteCodes, i);
    1.49 +                    int indx = i + readShortArg(byteCodes, i);
    1.50                      emitIf(out, "if (@1 > 0) ",
    1.51                           smapper.popI(), i, indx, topMostLabel);
    1.52                      i += 2;
    1.53                      break;
    1.54                  }
    1.55                  case opc_ifge: {
    1.56 -                    int indx = i + readIntArg(byteCodes, i);
    1.57 +                    int indx = i + readShortArg(byteCodes, i);
    1.58                      emitIf(out, "if (@1 >= 0) ",
    1.59                           smapper.popI(), i, indx, topMostLabel);
    1.60                      i += 2;
    1.61                      break;
    1.62                  }
    1.63                  case opc_ifnonnull: {
    1.64 -                    int indx = i + readIntArg(byteCodes, i);
    1.65 +                    int indx = i + readShortArg(byteCodes, i);
    1.66                      emitIf(out, "if (@1 !== null) ",
    1.67                           smapper.popA(), i, indx, topMostLabel);
    1.68                      i += 2;
    1.69                      break;
    1.70                  }
    1.71                  case opc_ifnull: {
    1.72 -                    int indx = i + readIntArg(byteCodes, i);
    1.73 +                    int indx = i + readShortArg(byteCodes, i);
    1.74                      emitIf(out, "if (@1 === null) ",
    1.75                           smapper.popA(), i, indx, topMostLabel);
    1.76                      i += 2;
    1.77 @@ -900,7 +900,7 @@
    1.78                                     ">=", topMostLabel);
    1.79                      break;
    1.80                  case opc_goto: {
    1.81 -                    int indx = i + readIntArg(byteCodes, i);
    1.82 +                    int indx = i + readShortArg(byteCodes, i);
    1.83                      goTo(out, i, indx, topMostLabel);
    1.84                      i += 2;
    1.85                      break;
    1.86 @@ -927,7 +927,7 @@
    1.87                      i = invokeStaticMethod(byteCodes, i, smapper, true);
    1.88                      break;
    1.89                  case opc_new: {
    1.90 -                    int indx = readIntArg(byteCodes, i);
    1.91 +                    int indx = readUShortArg(byteCodes, i);
    1.92                      String ci = jc.getClassName(indx);
    1.93                      emit(out, "var @1 = new @2;",
    1.94                           smapper.pushA(), accessClass(ci.replace('/', '_')));
    1.95 @@ -940,13 +940,13 @@
    1.96                      generateNewArray(atype, smapper);
    1.97                      break;
    1.98                  case opc_anewarray: {
    1.99 -                    int type = readIntArg(byteCodes, i);
   1.100 +                    int type = readUShortArg(byteCodes, i);
   1.101                      i += 2;
   1.102                      generateANewArray(type, smapper);
   1.103                      break;
   1.104                  }
   1.105                  case opc_multianewarray: {
   1.106 -                    int type = readIntArg(byteCodes, i);
   1.107 +                    int type = readUShortArg(byteCodes, i);
   1.108                      i += 2;
   1.109                      i = generateMultiANewArray(type, byteCodes, i, smapper);
   1.110                      break;
   1.111 @@ -1162,11 +1162,11 @@
   1.112                  case opc_sipush:
   1.113                      emit(out, "var @1 = @2;",
   1.114                           smapper.pushI(),
   1.115 -                         Integer.toString(readIntArg(byteCodes, i)));
   1.116 +                         Integer.toString(readShortArg(byteCodes, i)));
   1.117                      i += 2;
   1.118                      break;
   1.119                  case opc_getfield: {
   1.120 -                    int indx = readIntArg(byteCodes, i);
   1.121 +                    int indx = readUShortArg(byteCodes, i);
   1.122                      String[] fi = jc.getFieldInfoName(indx);
   1.123                      final int type = VarType.fromFieldType(fi[2].charAt(0));
   1.124                      final String mangleClass = mangleSig(fi[0]);
   1.125 @@ -1179,7 +1179,7 @@
   1.126                      break;
   1.127                  }
   1.128                  case opc_putfield: {
   1.129 -                    int indx = readIntArg(byteCodes, i);
   1.130 +                    int indx = readUShortArg(byteCodes, i);
   1.131                      String[] fi = jc.getFieldInfoName(indx);
   1.132                      final int type = VarType.fromFieldType(fi[2].charAt(0));
   1.133                      final String mangleClass = mangleSig(fi[0]);
   1.134 @@ -1193,7 +1193,7 @@
   1.135                      break;
   1.136                  }
   1.137                  case opc_getstatic: {
   1.138 -                    int indx = readIntArg(byteCodes, i);
   1.139 +                    int indx = readUShortArg(byteCodes, i);
   1.140                      String[] fi = jc.getFieldInfoName(indx);
   1.141                      final int type = VarType.fromFieldType(fi[2].charAt(0));
   1.142                      emit(out, "var @1 = @2(false)._@3();",
   1.143 @@ -1204,7 +1204,7 @@
   1.144                      break;
   1.145                  }
   1.146                  case opc_putstatic: {
   1.147 -                    int indx = readIntArg(byteCodes, i);
   1.148 +                    int indx = readUShortArg(byteCodes, i);
   1.149                      String[] fi = jc.getFieldInfoName(indx);
   1.150                      final int type = VarType.fromFieldType(fi[2].charAt(0));
   1.151                      emit(out, "@1(false)._@2(@3);",
   1.152 @@ -1215,13 +1215,13 @@
   1.153                      break;
   1.154                  }
   1.155                  case opc_checkcast: {
   1.156 -                    int indx = readIntArg(byteCodes, i);
   1.157 +                    int indx = readUShortArg(byteCodes, i);
   1.158                      generateCheckcast(indx, smapper);
   1.159                      i += 2;
   1.160                      break;
   1.161                  }
   1.162                  case opc_instanceof: {
   1.163 -                    int indx = readIntArg(byteCodes, i);
   1.164 +                    int indx = readUShortArg(byteCodes, i);
   1.165                      generateInstanceOf(indx, smapper);
   1.166                      i += 2;
   1.167                      break;
   1.168 @@ -1273,7 +1273,7 @@
   1.169      }
   1.170  
   1.171      private int generateIf(byte[] byteCodes, int i, final Variable v2, final Variable v1, final String test, int topMostLabel) throws IOException {
   1.172 -        int indx = i + readIntArg(byteCodes, i);
   1.173 +        int indx = i + readShortArg(byteCodes, i);
   1.174          out.append("if (").append(v1)
   1.175             .append(' ').append(test).append(' ')
   1.176             .append(v2).append(") ");
   1.177 @@ -1281,11 +1281,6 @@
   1.178          return i + 2;
   1.179      }
   1.180      
   1.181 -    private int readIntArg(byte[] byteCodes, int offsetInstruction) {
   1.182 -        final int indxHi = byteCodes[offsetInstruction + 1] << 8;
   1.183 -        final int indxLo = byteCodes[offsetInstruction + 2];
   1.184 -        return (indxHi & 0xffffff00) | (indxLo & 0xff);
   1.185 -    }
   1.186      private int readInt4(byte[] byteCodes, int offset) {
   1.187          final int d = byteCodes[offset + 0] << 24;
   1.188          final int c = byteCodes[offset + 1] << 16;
   1.189 @@ -1293,18 +1288,25 @@
   1.190          final int a = byteCodes[offset + 3];
   1.191          return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff);
   1.192      }
   1.193 -    private int readUByte(byte[] byteCodes, int offset) {
   1.194 +    private static int readUByte(byte[] byteCodes, int offset) {
   1.195          return byteCodes[offset] & 0xff;
   1.196      }
   1.197  
   1.198 -    private int readUShort(byte[] byteCodes, int offset) {
   1.199 +    private static int readUShort(byte[] byteCodes, int offset) {
   1.200          return ((byteCodes[offset] & 0xff) << 8)
   1.201                      | (byteCodes[offset + 1] & 0xff);
   1.202      }
   1.203 +    private static int readUShortArg(byte[] byteCodes, int offsetInstruction) {
   1.204 +        return readUShort(byteCodes, offsetInstruction + 1);
   1.205 +    }
   1.206  
   1.207 -    private int readShort(byte[] byteCodes, int offset) {
   1.208 -        return (byteCodes[offset] << 8)
   1.209 -                    | (byteCodes[offset + 1] & 0xff);
   1.210 +    private static int readShort(byte[] byteCodes, int offset) {
   1.211 +        int signed = byteCodes[offset];
   1.212 +        byte b0 = (byte)signed;
   1.213 +        return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
   1.214 +    }
   1.215 +    private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
   1.216 +        return readShort(byteCodes, offsetInstruction + 1);
   1.217      }
   1.218  
   1.219      private static void countArgs(String descriptor, char[] returnType, StringBuilder sig, StringBuilder cnt) {
   1.220 @@ -1432,7 +1434,7 @@
   1.221  
   1.222      private int invokeStaticMethod(byte[] byteCodes, int i, final StackMapper mapper, boolean isStatic)
   1.223      throws IOException {
   1.224 -        int methodIndex = readIntArg(byteCodes, i);
   1.225 +        int methodIndex = readUShortArg(byteCodes, i);
   1.226          String[] mi = jc.getFieldInfoName(methodIndex);
   1.227          char[] returnType = { 'V' };
   1.228          StringBuilder cnt = new StringBuilder();
   1.229 @@ -1477,7 +1479,7 @@
   1.230      }
   1.231      private int invokeVirtualMethod(byte[] byteCodes, int i, final StackMapper mapper)
   1.232      throws IOException {
   1.233 -        int methodIndex = readIntArg(byteCodes, i);
   1.234 +        int methodIndex = readUShortArg(byteCodes, i);
   1.235          String[] mi = jc.getFieldInfoName(methodIndex);
   1.236          char[] returnType = { 'V' };
   1.237          StringBuilder cnt = new StringBuilder();
     2.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java	Wed Mar 20 14:01:43 2013 +0100
     2.2 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java	Wed Mar 20 21:24:36 2013 +0100
     2.3 @@ -17,6 +17,7 @@
     2.4   */
     2.5  package org.apidesign.bck2brwsr.tck;
     2.6  
     2.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     2.8  import org.apidesign.bck2brwsr.vmtest.Compare;
     2.9  import org.apidesign.bck2brwsr.vmtest.VMTest;
    2.10  import org.testng.annotations.Factory;
    2.11 @@ -94,6 +95,50 @@
    2.12      @Compare public byte divisionReminder() {
    2.13          return mod((byte)1, (byte)2);
    2.14      }
    2.15 +
    2.16 +    private static int readShort(byte[] byteCodes, int offset) {
    2.17 +        int signed = byteCodes[offset];
    2.18 +        byte b0 = (byte)signed;
    2.19 +        return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
    2.20 +    }
    2.21 +    
    2.22 +    private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
    2.23 +        return readShort(byteCodes, offsetInstruction + 1);
    2.24 +    }
    2.25 +    
    2.26 +    @Compare public int readIntArgs255and156() {
    2.27 +        final byte[] arr = new byte[] { (byte)0, (byte)255, (byte)156 };
    2.28 +        
    2.29 +        assert arr[1] == -1 : "First byte: " + arr[1];
    2.30 +        assert arr[2] == -100 : "Second byte: " + arr[2];
    2.31 +        final int ret = readShortArg(arr, 0);
    2.32 +        assert ret < 65000: "Value: " + ret;
    2.33 +        return ret;
    2.34 +    }
    2.35 +    
    2.36 +    @JavaScriptBody(args = { "arr" }, body = "arr[1] = 255; arr[2] = 156; return arr;")
    2.37 +    private static byte[] fill255and156(byte[] arr) {
    2.38 +        arr[1] = (byte)255;
    2.39 +        arr[2] = (byte)156;
    2.40 +        return arr;
    2.41 +    }
    2.42 +
    2.43 +    @Compare public int readIntArgs255and156JSArray() {
    2.44 +        final byte[] arr = fill255and156(new byte[] { 0, 0, 0 });
    2.45 +        
    2.46 +        final int ret = readShortArg(arr, 0);
    2.47 +        assert ret < 65000: "Value: " + ret;
    2.48 +        return ret;
    2.49 +    }
    2.50 +    
    2.51 +    @Compare public int readIntArgsMinus1andMinus100() {
    2.52 +        final byte[] arr = new byte[] { (byte)0, (byte)-1, (byte)-100 };
    2.53 +        
    2.54 +        assert arr[1] == -1 : "First byte: " + arr[1];
    2.55 +        assert arr[2] == -100 : "Second byte: " + arr[2];
    2.56 +        
    2.57 +        return readShortArg(arr, 0);
    2.58 +    }
    2.59      
    2.60      @Factory
    2.61      public static Object[] create() {