1.1 --- a/emul/src/main/java/java/lang/Object.java Sat Jan 12 15:40:20 2013 +0100
1.2 +++ b/emul/src/main/java/java/lang/Object.java Sat Jan 12 15:44:09 2013 +0100
1.3 @@ -106,11 +106,14 @@
1.4 */
1.5 @JavaScriptBody(args = "self", body =
1.6 "if (self.$hashCode) return self.$hashCode;\n"
1.7 - + "var h = Math.random() * Math.pow(2, 32);\n"
1.8 + + "var h = self.computeHashCode__I(self);\n"
1.9 + "return self.$hashCode = h & h;"
1.10 )
1.11 public native int hashCode();
1.12
1.13 + @JavaScriptBody(args = "self", body = "Math.random() * Math.pow(2, 32);")
1.14 + native int computeHashCode();
1.15 +
1.16 /**
1.17 * Indicates whether some other object is "equal to" this one.
1.18 * <p>
2.1 --- a/emul/src/main/java/java/lang/String.java Sat Jan 12 15:40:20 2013 +0100
2.2 +++ b/emul/src/main/java/java/lang/String.java Sat Jan 12 15:44:09 2013 +0100
2.3 @@ -108,10 +108,6 @@
2.4 public final class String
2.5 implements java.io.Serializable, Comparable<String>, CharSequence
2.6 {
2.7 - @JavaScriptOnly
2.8 - /** Cache the hash code for the string */
2.9 - private int hash; // Default to 0
2.10 -
2.11 /** real string to delegate to */
2.12 private Object r;
2.13
2.14 @@ -1491,26 +1487,18 @@
2.15 *
2.16 * @return a hash code value for this object.
2.17 */
2.18 - @JavaScriptBody(args = "self", body =
2.19 - "var h = 0;\n" +
2.20 - "var s = self.toString();\n" +
2.21 - "for (var i = 0; i < s.length; i++) {\n" +
2.22 - " var high = (h >> 16) & 0xffff, low = h & 0xffff;\n" +
2.23 - " h = (((((31 * high) & 0xffff) << 16) >>> 0) + (31 * low) + s.charCodeAt(i)) & 0xffffffff;\n" +
2.24 - "}\n" +
2.25 - "return h;\n"
2.26 - )
2.27 public int hashCode() {
2.28 - int h = hash;
2.29 + return super.hashCode();
2.30 + }
2.31 + int computeHashCode() {
2.32 + int h = 0;
2.33 if (h == 0 && length() > 0) {
2.34 int off = offset();
2.35 - char val[] = toCharArray();
2.36 int len = length();
2.37
2.38 for (int i = 0; i < len; i++) {
2.39 - h = 31*h + val[off++];
2.40 + h = 31*h + charAt(off++);
2.41 }
2.42 - hash = h;
2.43 }
2.44 return h;
2.45 }
2.46 @@ -2742,7 +2730,6 @@
2.47 * of this string and whose contents are initialized to contain
2.48 * the character sequence represented by this string.
2.49 */
2.50 - @JavaScriptBody(args = "self", body = "return self.toString().split('');")
2.51 public char[] toCharArray() {
2.52 char result[] = new char[length()];
2.53 getChars(0, length(), result, 0);
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Jan 12 15:40:20 2013 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Jan 12 15:44:09 2013 +0100
3.3 @@ -491,7 +491,7 @@
3.4 emit(out, "@1 = @2;", lmapper.setD(3), smapper.popD());
3.5 break;
3.6 case opc_iadd:
3.7 - emit(out, "@1 += @2;", smapper.getI(1), smapper.popI());
3.8 + emit(out, "@1 = (@1 + @2) | 0;", smapper.getI(1), smapper.popI());
3.9 break;
3.10 case opc_ladd:
3.11 emit(out, "@1 += @2;", smapper.getL(1), smapper.popL());
3.12 @@ -503,7 +503,7 @@
3.13 emit(out, "@1 += @2;", smapper.getD(1), smapper.popD());
3.14 break;
3.15 case opc_isub:
3.16 - emit(out, "@1 -= @2;", smapper.getI(1), smapper.popI());
3.17 + emit(out, "@1 = (@1 - @2) | 0;", smapper.getI(1), smapper.popI());
3.18 break;
3.19 case opc_lsub:
3.20 emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
3.21 @@ -515,7 +515,7 @@
3.22 emit(out, "@1 -= @2;", smapper.getD(1), smapper.popD());
3.23 break;
3.24 case opc_imul:
3.25 - emit(out, "@1 *= @2;", smapper.getI(1), smapper.popI());
3.26 + emit(out, "@1 = (((@1 * (@2 >> 16)) << 16) + @1 * (@2 & 0xFFFF)) | 0;", smapper.getI(1), smapper.popI());
3.27 break;
3.28 case opc_lmul:
3.29 emit(out, "@1 *= @2;", smapper.getL(1), smapper.popL());
4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java Sat Jan 12 15:40:20 2013 +0100
4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java Sat Jan 12 15:44:09 2013 +0100
4.3 @@ -39,6 +39,10 @@
4.4 return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
4.5 }
4.6
4.7 + @Compare public int hashOfInt() {
4.8 + return Integer.valueOf(Integer.MAX_VALUE).hashCode();
4.9 + }
4.10 +
4.11 @Factory
4.12 public static Object[] create() {
4.13 return VMTest.create(CompareHashTest.class);
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Sat Jan 12 15:44:09 2013 +0100
5.3 @@ -0,0 +1,98 @@
5.4 +/**
5.5 + * Back 2 Browser Bytecode Translator
5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 + *
5.8 + * This program is free software: you can redistribute it and/or modify
5.9 + * it under the terms of the GNU General Public License as published by
5.10 + * the Free Software Foundation, version 2 of the License.
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details.
5.16 + *
5.17 + * You should have received a copy of the GNU General Public License
5.18 + * along with this program. Look for COPYING file in the top folder.
5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
5.20 + */
5.21 +package org.apidesign.bck2brwsr.tck;
5.22 +
5.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
5.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
5.25 +import org.testng.annotations.Factory;
5.26 +
5.27 +/**
5.28 + *
5.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.30 + */
5.31 +public class IntegerArithmeticTest {
5.32 +
5.33 + private static int add(int x, int y) {
5.34 + return x + y;
5.35 + }
5.36 +
5.37 + private static int sub(int x, int y) {
5.38 + return x - y;
5.39 + }
5.40 +
5.41 + private static int mul(int x, int y) {
5.42 + return x * y;
5.43 + }
5.44 +
5.45 + private static int div(int x, int y) {
5.46 + return x / y;
5.47 + }
5.48 +
5.49 + private static int mod(int x, int y) {
5.50 + return x % y;
5.51 + }
5.52 +
5.53 + @Compare public int addOverflow() {
5.54 + return add(Integer.MAX_VALUE, 1);
5.55 + }
5.56 +
5.57 + @Compare public int subUnderflow() {
5.58 + return sub(Integer.MIN_VALUE, 1);
5.59 + }
5.60 +
5.61 + @Compare public int addMaxIntAndMaxInt() {
5.62 + return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
5.63 + }
5.64 +
5.65 + @Compare public int subMinIntAndMinInt() {
5.66 + return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
5.67 + }
5.68 +
5.69 + @Compare public int multiplyMaxInt() {
5.70 + return mul(Integer.MAX_VALUE, 2);
5.71 + }
5.72 +
5.73 + @Compare public int multiplyMaxIntAndMaxInt() {
5.74 + return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
5.75 + }
5.76 +
5.77 + @Compare public int multiplyMinInt() {
5.78 + return mul(Integer.MIN_VALUE, 2);
5.79 + }
5.80 +
5.81 + @Compare public int multiplyMinIntAndMinInt() {
5.82 + return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
5.83 + }
5.84 +
5.85 + @Compare public int multiplyPrecision() {
5.86 + return mul(119106029, 1103515245);
5.87 + }
5.88 +
5.89 + @Compare public int division() {
5.90 + return div(1, 2);
5.91 + }
5.92 +
5.93 + @Compare public int divisionReminder() {
5.94 + return mod(1, 2);
5.95 + }
5.96 +
5.97 + @Factory
5.98 + public static Object[] create() {
5.99 + return VMTest.create(IntegerArithmeticTest.class);
5.100 + }
5.101 +}