# HG changeset patch # User Jaroslav Tulach # Date 1351632138 -3600 # Node ID 8db5cf267d749a6dec167d42567b7daf327bad79 # Parent 5134b17d623ced5f3f703564633ae34dce36fd0a Implementation of multianewarray bytecode instruction diff -r 5134b17d623c -r 8db5cf267d74 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Oct 30 20:29:55 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Oct 30 22:22:18 2012 +0100 @@ -236,7 +236,7 @@ for (int i = 0; i < byteCodes.length; i++) { int prev = i; out.append(" case " + i).append(": "); - final int c = (byteCodes[i] + 256) % 256; + final int c = readByte(byteCodes, i); switch (c) { case bc_aload_0: case bc_iload_0: @@ -271,7 +271,7 @@ case bc_fload: case bc_dload: case bc_aload: { - final int indx = (byteCodes[++i] + 256) % 256; + final int indx = readByte(byteCodes, ++i); out.append("stack.push(arg").append(indx + ");"); break; } @@ -280,7 +280,7 @@ case bc_fstore: case bc_dstore: case bc_astore: { - final int indx = (byteCodes[++i] + 256) % 256; + final int indx = readByte(byteCodes, ++i); out.append("arg" + indx).append(" = stack.pop()"); break; } @@ -369,7 +369,7 @@ out.append("{ var v = stack.pop(); stack.push(stack.pop() >>> v); }"); break; case bc_iinc: { - final int varIndx = (byteCodes[++i] + 256) % 256; + final int varIndx = readByte(byteCodes, ++i); final int incrBy = byteCodes[++i]; if (incrBy == 1) { out.append("arg" + varIndx).append("++;"); @@ -442,7 +442,7 @@ out.append("stack.push(5);"); break; case bc_ldc: { - int indx = byteCodes[++i]; + int indx = readByte(byteCodes, ++i); CPEntry entry = jc.getConstantPool().get(indx); String v = encodeConstant(entry); out.append("stack.push(").append(v).append(");"); @@ -553,7 +553,7 @@ break; } case bc_lookupswitch: { - int table = (i - 1) / 4 * 4 + 4; + int table = i / 4 * 4 + 4; int dflt = i + readInt4(byteCodes, table); table += 4; int n = readInt4(byteCodes, table); @@ -571,7 +571,7 @@ break; } case bc_tableswitch: { - int table = (i - 1) / 4 * 4 + 4; + int table = i / 4 * 4 + 4; int dflt = i + readInt4(byteCodes, table); table += 4; int low = readInt4(byteCodes, table); @@ -622,6 +622,26 @@ out.append("stack.push(new Array(stack.pop()));"); break; } + case bc_multianewarray: { + i += 2; + int dim = readByte(byteCodes, ++i); + out.append("{ var a0 = new Array(stack.pop());"); + for (int d = 1; d < dim; d++) { + out.append("\n var l" + d).append(" = stack.pop();"); + out.append("\n for (var i" + d).append (" = 0; i" + d). + append(" < a" + (d - 1)). + append(".length; i" + d).append("++) {"); + out.append("\n var a" + d). + append (" = new Array(l" + d).append(");"); + out.append("\n a" + (d - 1)).append("[i" + d).append("] = a" + d). + append(";"); + } + for (int d = 1; d < dim; d++) { + out.append("\n }"); + } + out.append("\nstack.push(a0); }"); + break; + } case bc_arraylength: out.append("stack.push(stack.pop().length);"); break; @@ -731,7 +751,7 @@ out.append(" //"); for (int j = prev; j <= i; j++) { out.append(" "); - final int cc = (byteCodes[j] + 256) % 256; + final int cc = readByte(byteCodes, j); out.append(Integer.toString(cc)); } out.append("\n"); @@ -758,6 +778,9 @@ final int a = byteCodes[offsetInstruction + 3]; return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff); } + private int readByte(byte[] byteCodes, int offsetInstruction) { + return (byteCodes[offsetInstruction] + 256) % 256; + } private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) { int cnt = 0; diff -r 5134b17d623c -r 8db5cf267d74 vm/src/test/java/org/apidesign/vm4brwsr/Array.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Tue Oct 30 20:29:55 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Tue Oct 30 22:22:18 2012 +0100 @@ -53,8 +53,12 @@ private static final Array[] ARR = { new Array(), new Array(), new Array() }; - private static Array[] arr() { - return ARR; + private static Array[][] arr() { + Array[][] matrix = new Array[3][3]; + for (int i = 0; i < ARR.length; i++) { + matrix[i][i] = ARR[i]; + } + return matrix; } private static T[] filter(T[] in) { return in; @@ -62,12 +66,19 @@ public static double sum() { double sum = 0.0; - for (int i = 0; i < arr().length; i++) { - sum += arr()[i].bytes(); - sum += arr()[i].shorts(); - sum += arr()[i].ints()[2]; - sum += arr()[i].floats(); - sum += filter(arr())[i].doubles(); + for (Array[] row : arr()) { + int indx = -1; + for (Array a : row) { + indx++; + if (a == null) { + continue; + } + sum += a.bytes(); + sum += a.shorts(); + sum += a.ints()[2]; + sum += a.floats(); + sum += filter(row)[indx].doubles(); + } } return sum; } @@ -75,8 +86,8 @@ int[] arr = { 0, 1, 2, 3, 4, 5 }; int sum = 0; - for (int i = 0; i < arr.length; i++) { - sum += arr[i]; + for (int a : arr) { + sum += a; } return sum; } @@ -89,7 +100,7 @@ public static char copyArray() { char[] arr = { '0' }; - arraycopy(arr()[0].chars, 0, arr, 0, 1); + arraycopy(arr()[0][0].chars, 0, arr, 0, 1); return arr[0]; } } diff -r 5134b17d623c -r 8db5cf267d74 vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Tue Oct 30 20:29:55 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Tue Oct 30 22:22:18 2012 +0100 @@ -36,9 +36,9 @@ import javax.script.Invocable; import javax.script.ScriptException; -import org.testng.annotations.Test; import static org.testng.Assert.*; import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; /** * @@ -50,6 +50,11 @@ Double.valueOf(15) ); } + + @Test public void realOperationOnArrays() throws Exception { + assertEquals(Array.sum(), 105.0, "Computes to 105"); + } + @Test public void verifyOperationsOnArrays() throws Exception { assertExec("The sum is 105", "org_apidesign_vm4brwsr_Array_sumD", Double.valueOf(105)