# HG changeset patch # User Jaroslav Tulach # Date 1346070426 -7200 # Node ID d3193a7086e7915c6b10926e6e0abd4454aae8a4 # Parent f352a33fb71bdc730437b5a1832bb7efe8a506cf Support for factorial computed with a for cycle diff -r f352a33fb71b -r d3193a7086e7 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Aug 27 14:27:06 2012 +0200 @@ -0,0 +1,1 @@ +^target/.* diff -r f352a33fb71b -r d3193a7086e7 src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 13:16:29 2012 +0200 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 14:27:06 2012 +0200 @@ -79,14 +79,12 @@ index++; } } - out.append(") {").append("\n var "); + out.append(") {").append("\n"); final Code code = m.getCode(); int len = code.getMaxLocals(); - space = ""; - for (int i = 0; i < len; i++) { - out.append(space); - out.append("var").append(String.valueOf(i)); - space = ","; + for (int index = args.size(), i = args.size(); i < len; i++) { + out.append(" var "); + out.append("arg").append(String.valueOf(i)).append(";\n"); } out.append(";\n var stack = new Array("); out.append(Integer.toString(code.getMaxStack())); @@ -139,6 +137,30 @@ out.append("stack.push(arg").append(indx + ");"); break; } + case bc_istore_0: + case bc_lstore_0: + case bc_fstore_0: + case bc_dstore_0: + out.append("arg0 = stack.pop();"); + break; + case bc_istore_1: + case bc_lstore_1: + case bc_fstore_1: + case bc_dstore_1: + out.append("arg1 = stack.pop();"); + break; + case bc_istore_2: + case bc_lstore_2: + case bc_fstore_2: + case bc_dstore_2: + out.append("arg2 = stack.pop();"); + break; + case bc_istore_3: + case bc_lstore_3: + case bc_fstore_3: + case bc_dstore_3: + out.append("arg3 = stack.pop();"); + break; case bc_iadd: case bc_ladd: case bc_fadd: @@ -165,6 +187,16 @@ case bc_ddiv: out.append("{ var tmp = stack.pop(); stack.push(stack.pop() / tmp); }"); break; + case bc_iinc: { + final int varIndx = (byteCodes[++i] + 256) % 256; + final int incrBy = (byteCodes[++i] + 256) % 256; + if (incrBy == 1) { + out.append("arg" + varIndx).append("++;"); + } else { + out.append("arg" + varIndx).append(" += " + incrBy).append(";"); + } + break; + } case bc_ireturn: case bc_lreturn: case bc_freturn: @@ -237,6 +269,12 @@ case bc_if_icmpge: i = generateIf(byteCodes, i, "<="); break; + case bc_goto: { + int indx = i + readIntArg(byteCodes, i); + out.append("gt = " + indx).append("; continue;"); + i += 2; + break; + } case bc_invokestatic: { int methodIndex = readIntArg(byteCodes, i); CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex); @@ -286,9 +324,9 @@ } private int readIntArg(byte[] byteCodes, int offsetInstruction) { - final int indxHi = (byteCodes[offsetInstruction + 1] + 256) % 256; - final int indxLo = (byteCodes[offsetInstruction + 2] + 256) % 256; - return (indxHi << 16) + indxLo; + final int indxHi = byteCodes[offsetInstruction + 1] << 8; + final int indxLo = byteCodes[offsetInstruction + 2]; + return (indxHi & 0xffffff00) | (indxLo & 0xff); } private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) { diff -r f352a33fb71b -r d3193a7086e7 src/test/java/org/apidesign/java4browser/StaticMethod.java --- a/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 13:16:29 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 14:27:06 2012 +0200 @@ -44,4 +44,11 @@ return n * factRec(n - 1); } } + public static long factIter(int n) { + long res = 1; + for (int i = 2; i <= n; i++) { + res *= i; + } + return res; + } } diff -r f352a33fb71b -r d3193a7086e7 src/test/java/org/apidesign/java4browser/StaticMethodTest.java --- a/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 13:16:29 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 14:27:06 2012 +0200 @@ -82,6 +82,14 @@ 5 ); } + @Test public void factIter() throws Exception { + assertExec( + "Factorial of 5 is 120", + "org_apidesign_java4browser_StaticMethod_factIterJI", + Double.valueOf(120), + 5 + ); + } private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception { StringBuilder sb = new StringBuilder(); @@ -90,6 +98,8 @@ Object ret = null; try { ret = i.invokeFunction(methodName, args); + } catch (ScriptException ex) { + fail("Execution failed in " + sb, ex); } catch (NoSuchMethodException ex) { fail("Cannot find method in " + sb, ex); }