Merging in integer arithmetic by Martin
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 12 Jan 2013 15:44:09 +0100
changeset 431d859199a15b7
parent 430 b4940ef87438
parent 429 7c4442271367
child 432 1bdeeb77f5a3
Merging in integer arithmetic by Martin
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java
     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 +}