# HG changeset patch # User Jaroslav Tulach # Date 1363811076 -3600 # Node ID 8ece59d31fcf5b04e10bb873cbd74d733a117f2d # Parent 467ae5eb67f0bc79657156380cb9a8b551da6463 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. diff -r 467ae5eb67f0 -r 8ece59d31fcf rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Mar 20 14:01:43 2013 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Mar 20 21:24:36 2013 +0100 @@ -782,7 +782,7 @@ } case opc_ldc_w: case opc_ldc2_w: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); i += 2; String v = encodeConstant(indx); int type = VarType.fromConstantType(jc.getTag(indx)); @@ -824,56 +824,56 @@ "==", topMostLabel); break; case opc_ifeq: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 == 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_ifne: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 != 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_iflt: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 < 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_ifle: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 <= 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_ifgt: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 > 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_ifge: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 >= 0) ", smapper.popI(), i, indx, topMostLabel); i += 2; break; } case opc_ifnonnull: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 !== null) ", smapper.popA(), i, indx, topMostLabel); i += 2; break; } case opc_ifnull: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); emitIf(out, "if (@1 === null) ", smapper.popA(), i, indx, topMostLabel); i += 2; @@ -900,7 +900,7 @@ ">=", topMostLabel); break; case opc_goto: { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); goTo(out, i, indx, topMostLabel); i += 2; break; @@ -927,7 +927,7 @@ i = invokeStaticMethod(byteCodes, i, smapper, true); break; case opc_new: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); String ci = jc.getClassName(indx); emit(out, "var @1 = new @2;", smapper.pushA(), accessClass(ci.replace('/', '_'))); @@ -940,13 +940,13 @@ generateNewArray(atype, smapper); break; case opc_anewarray: { - int type = readIntArg(byteCodes, i); + int type = readUShortArg(byteCodes, i); i += 2; generateANewArray(type, smapper); break; } case opc_multianewarray: { - int type = readIntArg(byteCodes, i); + int type = readUShortArg(byteCodes, i); i += 2; i = generateMultiANewArray(type, byteCodes, i, smapper); break; @@ -1162,11 +1162,11 @@ case opc_sipush: emit(out, "var @1 = @2;", smapper.pushI(), - Integer.toString(readIntArg(byteCodes, i))); + Integer.toString(readShortArg(byteCodes, i))); i += 2; break; case opc_getfield: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); final String mangleClass = mangleSig(fi[0]); @@ -1179,7 +1179,7 @@ break; } case opc_putfield: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); final String mangleClass = mangleSig(fi[0]); @@ -1193,7 +1193,7 @@ break; } case opc_getstatic: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); emit(out, "var @1 = @2(false)._@3();", @@ -1204,7 +1204,7 @@ break; } case opc_putstatic: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); emit(out, "@1(false)._@2(@3);", @@ -1215,13 +1215,13 @@ break; } case opc_checkcast: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); generateCheckcast(indx, smapper); i += 2; break; } case opc_instanceof: { - int indx = readIntArg(byteCodes, i); + int indx = readUShortArg(byteCodes, i); generateInstanceOf(indx, smapper); i += 2; break; @@ -1273,7 +1273,7 @@ } private int generateIf(byte[] byteCodes, int i, final Variable v2, final Variable v1, final String test, int topMostLabel) throws IOException { - int indx = i + readIntArg(byteCodes, i); + int indx = i + readShortArg(byteCodes, i); out.append("if (").append(v1) .append(' ').append(test).append(' ') .append(v2).append(") "); @@ -1281,11 +1281,6 @@ return i + 2; } - private int readIntArg(byte[] byteCodes, int offsetInstruction) { - final int indxHi = byteCodes[offsetInstruction + 1] << 8; - final int indxLo = byteCodes[offsetInstruction + 2]; - return (indxHi & 0xffffff00) | (indxLo & 0xff); - } private int readInt4(byte[] byteCodes, int offset) { final int d = byteCodes[offset + 0] << 24; final int c = byteCodes[offset + 1] << 16; @@ -1293,18 +1288,25 @@ final int a = byteCodes[offset + 3]; return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff); } - private int readUByte(byte[] byteCodes, int offset) { + private static int readUByte(byte[] byteCodes, int offset) { return byteCodes[offset] & 0xff; } - private int readUShort(byte[] byteCodes, int offset) { + private static int readUShort(byte[] byteCodes, int offset) { return ((byteCodes[offset] & 0xff) << 8) | (byteCodes[offset + 1] & 0xff); } + private static int readUShortArg(byte[] byteCodes, int offsetInstruction) { + return readUShort(byteCodes, offsetInstruction + 1); + } - private int readShort(byte[] byteCodes, int offset) { - return (byteCodes[offset] << 8) - | (byteCodes[offset + 1] & 0xff); + private static int readShort(byte[] byteCodes, int offset) { + int signed = byteCodes[offset]; + byte b0 = (byte)signed; + return (b0 << 8) | (byteCodes[offset + 1] & 0xff); + } + private static int readShortArg(byte[] byteCodes, int offsetInstruction) { + return readShort(byteCodes, offsetInstruction + 1); } private static void countArgs(String descriptor, char[] returnType, StringBuilder sig, StringBuilder cnt) { @@ -1432,7 +1434,7 @@ private int invokeStaticMethod(byte[] byteCodes, int i, final StackMapper mapper, boolean isStatic) throws IOException { - int methodIndex = readIntArg(byteCodes, i); + int methodIndex = readUShortArg(byteCodes, i); String[] mi = jc.getFieldInfoName(methodIndex); char[] returnType = { 'V' }; StringBuilder cnt = new StringBuilder(); @@ -1477,7 +1479,7 @@ } private int invokeVirtualMethod(byte[] byteCodes, int i, final StackMapper mapper) throws IOException { - int methodIndex = readIntArg(byteCodes, i); + int methodIndex = readUShortArg(byteCodes, i); String[] mi = jc.getFieldInfoName(methodIndex); char[] returnType = { 'V' }; StringBuilder cnt = new StringBuilder(); diff -r 467ae5eb67f0 -r 8ece59d31fcf rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java Wed Mar 20 14:01:43 2013 +0100 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java Wed Mar 20 21:24:36 2013 +0100 @@ -17,6 +17,7 @@ */ package org.apidesign.bck2brwsr.tck; +import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.apidesign.bck2brwsr.vmtest.Compare; import org.apidesign.bck2brwsr.vmtest.VMTest; import org.testng.annotations.Factory; @@ -94,6 +95,50 @@ @Compare public byte divisionReminder() { return mod((byte)1, (byte)2); } + + private static int readShort(byte[] byteCodes, int offset) { + int signed = byteCodes[offset]; + byte b0 = (byte)signed; + return (b0 << 8) | (byteCodes[offset + 1] & 0xff); + } + + private static int readShortArg(byte[] byteCodes, int offsetInstruction) { + return readShort(byteCodes, offsetInstruction + 1); + } + + @Compare public int readIntArgs255and156() { + final byte[] arr = new byte[] { (byte)0, (byte)255, (byte)156 }; + + assert arr[1] == -1 : "First byte: " + arr[1]; + assert arr[2] == -100 : "Second byte: " + arr[2]; + final int ret = readShortArg(arr, 0); + assert ret < 65000: "Value: " + ret; + return ret; + } + + @JavaScriptBody(args = { "arr" }, body = "arr[1] = 255; arr[2] = 156; return arr;") + private static byte[] fill255and156(byte[] arr) { + arr[1] = (byte)255; + arr[2] = (byte)156; + return arr; + } + + @Compare public int readIntArgs255and156JSArray() { + final byte[] arr = fill255and156(new byte[] { 0, 0, 0 }); + + final int ret = readShortArg(arr, 0); + assert ret < 65000: "Value: " + ret; + return ret; + } + + @Compare public int readIntArgsMinus1andMinus100() { + final byte[] arr = new byte[] { (byte)0, (byte)-1, (byte)-100 }; + + assert arr[1] == -1 : "First byte: " + arr[1]; + assert arr[2] == -100 : "Second byte: " + arr[2]; + + return readShortArg(arr, 0); + } @Factory public static Object[] create() {