blob: 9b28f6fc81caaf4ef783631dc98dff14a50038a3 [file] [log] [blame]
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs.test;
import com.google.gwt.junit.client.GWTTestCase;
/**
* Test direct uses of longs. Mostly this tests that LongLib is in fact being
* invoked in various cases. The behavior of LongLib itself is tested in
* LongLibTest.
*/
public class NativeLongTest extends GWTTestCase {
/**
* A class that wraps an int. See {@link NativeLongTest#testImplicitCastToLong()}.
*/
private static class IntegerWrapper {
private final int i;
public IntegerWrapper(int i) {
this.i = i;
}
public long longValue() {
return i; // implicit cast to long
}
}
private static class RequestIdFactory {
static RequestIdFactory instance = new RequestIdFactory();
static RequestIdFactory getInstance() {
return instance;
}
long nextId;
long getNextId() {
return nextId++;
}
}
/*
* These constants are done as volatile fields so that the compiler will not
* constant fold them. The problem is that if you write assertEquals(2L,
* 4L/2L), the compiler will emit assertEquals(2L, 2L).
*/
private static volatile byte BYTE_FOUR = (byte) 4;
private static volatile char CHAR_FOUR = (char) 4;
private static volatile boolean FALSE = false;
private static volatile int INT_FOUR = 4;
private static volatile long LONG_100 = 100L;
private static volatile long LONG_1234 = 0x1234123412341234L;
private static volatile long LONG_1234_DECIMAL = 1234123412341234L;
private static volatile long LONG_1234000012340000 = 0x1234000012340000L;
private static volatile long LONG_5DEECE66D = 0x5DEECE66DL;
private static volatile long LONG_B = 0xBL;
private static volatile long LONG_DEADBEEF = 0xdeadbeefdeadbeefL;
private static volatile long LONG_DEADBEEF12341234 = 0xdeadbeef12341234L;
private static volatile long LONG_FFFFFFFF = 0xFFFFFFFFL;
private static volatile long LONG_FOUR = 4L;
private static volatile long LONG_ONE = 1L;
private static volatile long LONG_THREE = 3L;
private static volatile long LONG_TWO = 2L;
private static volatile long LONG_TWO_PWR_32 = 0x100000000L;
private static volatile long LONG_ZERO = 0L;
private static volatile short SHORT_FOUR = (short) 4;
@Override
public String getModuleName() {
return "com.google.gwt.dev.jjs.CompilerSuite";
}
public void testArithmetic() {
assertEquals(-1089359682551557853L, LONG_1234 + LONG_DEADBEEF);
assertEquals(5024439901525534073L, 2 * LONG_1234 - LONG_DEADBEEF);
assertEquals(2476047018506819212L, LONG_1234 * LONG_DEADBEEF);
assertEquals(-240105308887621659L, LONG_DEADBEEF / 10);
assertEquals(-1089359682551557853L, LONG_DEADBEEF % LONG_1234);
}
public void testArrayInitializer() {
long[] longs = new long[3];
assertEquals(0L, longs[1]);
long[][] longs2 = new long[3][3];
assertEquals(0L, longs2[1][1]);
}
public void testCasts() {
assertEquals(0x12341234, (int) LONG_1234);
assertEquals(0x1234, (short) LONG_1234);
}
public void testConstants() {
assertEquals(LONG_5DEECE66D, LONG_5DEECE66D);
assertTrue(LONG_5DEECE66D > 0L);
assertTrue(0L < LONG_5DEECE66D);
assertEquals(LONG_B, LONG_B);
assertTrue(LONG_B > 0L);
assertTrue(0L < LONG_B);
}
public void testFor64Bits() {
long x = LONG_1234;
long y = LONG_1234 + LONG_ONE;
long z = y - x;
// with longs implemented as doubles, z will be 0 instead of 1
assertEquals(1L, z);
}
public void testImplicitCastFromLong() {
double d = LONG_ONE;
d += LONG_TWO;
assertEquals(0.0, 3L, d);
assertTrue(3L == d);
float f = LONG_ONE;
f += LONG_TWO;
assertEquals(0.0, 3L, f);
assertTrue(3L == f);
}
public void testImplicitCastToLong() {
long l = 10;
l += 5;
assertEquals(15, l);
assertTrue(15 == l);
// Issue 3710
IntegerWrapper wrap = new IntegerWrapper(20);
assertEquals(400L, wrap.longValue() * wrap.longValue());
}
public void testInlinedIntInitializer() {
long sum = 0; // int, not long!
assertEquals("0", "" + (sum / INT_FOUR));
}
public void testLogicalAnd() {
assertEquals(LONG_1234, LONG_1234 & -LONG_ONE);
assertEquals(0x12341234L, LONG_1234 & LONG_FFFFFFFF);
assertEquals(0L, LONG_ONE & LONG_ZERO);
assertEquals(1L, LONG_ONE & LONG_THREE);
}
public void testLogicalOr() {
assertEquals(-1L, LONG_1234 | -LONG_ONE);
assertEquals(0x12341234FFFFFFFFL, LONG_1234 | LONG_FFFFFFFF);
assertEquals(1L, LONG_ONE | LONG_ZERO);
assertEquals(3L, LONG_ONE | LONG_THREE);
}
public void testLogicalXor() {
assertTrue((255L ^ LONG_5DEECE66D) != 0);
assertEquals(0L, LONG_1234 ^ LONG_1234);
assertEquals(0x0000123400001234L, LONG_1234 ^ LONG_1234000012340000);
assertEquals(1L, LONG_ONE ^ LONG_ZERO);
assertEquals(2L, LONG_ONE ^ LONG_THREE);
}
public void testModifyingOps() {
long l = 20;
l += INT_FOUR;
assertEquals(25, ++l);
assertEquals(25, l++);
assertEquals(26, l);
l += BYTE_FOUR;
assertEquals(30, l);
l += CHAR_FOUR;
assertEquals(34, l);
l += SHORT_FOUR;
assertEquals(38, l);
l += INT_FOUR;
assertEquals(42, l);
}
public void testShift() {
assertEquals(LONG_5DEECE66D, LONG_5DEECE66D & ((LONG_ONE << 48) - 1));
assertEquals(LONG_ONE << 12, (LONG_ONE << 60) >>> (48));
assertTrue((LONG_ONE << 35) > (LONG_ONE << 30));
assertEquals(0x10L, LONG_ONE << BYTE_FOUR);
assertEquals(0x10L, LONG_ONE << CHAR_FOUR);
assertEquals(0x10L, LONG_ONE << SHORT_FOUR);
assertEquals(0x10L, LONG_ONE << INT_FOUR);
assertEquals(0x10L, LONG_ONE << LONG_FOUR);
assertEquals(1L, LONG_TWO_PWR_32 >> 32);
assertEquals(1L, LONG_TWO_PWR_32 >>> 32);
}
public void testStringAppend() {
long x = LONG_100;
assertEquals("100 is a long", x + " is a long");
assertEquals("a long: 100", "a long: " + x);
}
// Issue 1198
public void testToHexString() {
assertEquals("deadbeef12341234", Long.toHexString(LONG_DEADBEEF12341234));
}
public void testToString() {
assertEquals("1234123412341234", "" + LONG_1234_DECIMAL);
}
/**
* It's important when allocating a new temporary that it is marked as in use.
*/
public void testVariableReuseInCompoundAssignmentNormalizer1() {
if (FALSE) {
// Prevent inlining, so that CAN allocates temporaries predictably.
testVariableReuseInCompoundAssignmentNormalizer1();
}
assertEquals("0",
Long.toHexString(RequestIdFactory.getInstance().getNextId()));
}
/**
* Using differently typed temp variables can cause JArrayType to throw a
* class cast exception.
*/
public void testVariableReuseInCompoundAssignmentNormalizer2() {
if (FALSE) {
// Prevent inlining, so that CAN allocates temporaries predictably.
testVariableReuseInCompoundAssignmentNormalizer2();
}
long ary[][] = new long[10][10];
long i = 3, j = 3;
assertEquals(0L, ary[(int) i++][(int) j++]++);
assertEquals(4L, i);
assertEquals(4L, j);
assertEquals(1L, ary[3][3]);
}
/**
* Using differently typed temp variables can cause LongEmulationNormalizer to
* fail an assertion.
*/
public void testVariableReuseInCompoundAssignmentNormalizer3() {
if (FALSE) {
// Prevent inlining, so that CAN allocates temporaries predictably.
testVariableReuseInCompoundAssignmentNormalizer3();
}
long ary[] = new long[10];
int i = 3;
long j = 5;
assertEquals(0L, ary[i++]++);
assertEquals(4, i);
assertEquals(1L, ary[3]);
assertEquals(0L, ary[(int) j++]++);
assertEquals(6L, j);
assertEquals(1L, ary[5]);
}
}