All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.truffle.api.dsl.test.IdentityComparisonTest Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.oracle.truffle.api.dsl.test;

import org.junit.Assert;
import org.junit.Test;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;
import com.oracle.truffle.api.dsl.test.IdentityComparisonTestFactory.EqualityComparison1NodeGen;
import com.oracle.truffle.api.dsl.test.IdentityComparisonTestFactory.IdentityComparison1NodeGen;
import com.oracle.truffle.api.dsl.test.examples.ExampleTypes;
import com.oracle.truffle.api.nodes.Node;

public class IdentityComparisonTest {

    @Test
    public void testIdentityComparison() {
        IdentityComparison1Node node = IdentityComparison1NodeGen.create();
        Assert.assertEquals(true, node.execute(true));
        Assert.assertEquals((byte) 1, node.execute((byte) 1));
        Assert.assertEquals((short) 1, node.execute((short) 1));
        Assert.assertEquals((char) 1, node.execute((char) 1));
        Assert.assertEquals(1, node.execute(1));
        Assert.assertEquals(1L, node.execute(1L));
        Assert.assertEquals(1f, node.execute(1f));
        Assert.assertEquals(1d, node.execute(1d));

        // Double.NaN must fail because NaN must not be identity equal to NaN.
        // The DSL can optimize the == operator but must be careful with NaN values.
        // If the DSL optimizes the == operator it would not throw an unsupported
        // specialization exception
        try {
            node.execute(Double.NaN);
            Assert.fail();
        } catch (UnsupportedSpecializationException e) {
        }
        try {
            node.execute(Float.NaN);
            Assert.fail();
        } catch (UnsupportedSpecializationException e) {
        }
    }

    @SuppressWarnings("unused")
    @TypeSystemReference(ExampleTypes.class)
    abstract static class IdentityComparison1Node extends Node {

        public abstract Object execute(Object arg0);

        @Specialization(guards = "value == cachedValue")
        boolean s0(boolean value, @Cached("value") boolean cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        byte s1(byte value, @Cached("value") byte cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        short s2(short value, @Cached("value") short cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        char s3(char value, @Cached("value") char cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        int s4(int value, @Cached("value") int cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        long s5(long value, @Cached("value") long cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        float s6(float value, @Cached("value") float cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        double s7(double value, @Cached("value") double cachedValue) {
            return value;
        }

        @Specialization(guards = "value == cachedValue")
        String s8(String value, @Cached("value") String cachedValue) {
            return value;
        }
    }

    @Test
    public void testEqualityComparison() {
        EqualityComparison1Node node = EqualityComparison1NodeGen.create();
        Assert.assertEquals(true, node.execute(true));
        Assert.assertEquals((byte) 1, node.execute((byte) 1));
        Assert.assertEquals((short) 1, node.execute((short) 1));
        Assert.assertEquals((char) 1, node.execute((char) 1));
        Assert.assertEquals(1, node.execute(1));
        Assert.assertEquals(1L, node.execute(1L));
        Assert.assertEquals(1f, node.execute(1f));
        Assert.assertEquals(1d, node.execute(1d));

        /*
         * Equality for equals comparison of NaN can fold.
         */
        Assert.assertEquals(Double.NaN, node.execute(Double.NaN));
        Assert.assertEquals(Float.NaN, node.execute(Float.NaN));

        MyClass myClassValue = new MyClass();

        Assert.assertSame(myClassValue, node.execute(myClassValue));
        // for the first execution we never need to call equals
        Assert.assertEquals(0, myClassValue.equalsCalled);

        Assert.assertSame(myClassValue, node.execute(myClassValue));
        // the second iteration requires one equals call for the cache
        Assert.assertEquals(1, myClassValue.equalsCalled);
    }

    @SuppressWarnings("unused")
    @TypeSystemReference(ExampleTypes.class)
    abstract static class EqualityComparison1Node extends Node {

        public abstract Object execute(Object arg0);

        @Specialization(guards = "value.equals(cachedValue)")
        Boolean s0(Boolean value, @Cached("value") Boolean cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Byte s1(Byte value, @Cached("value") Byte cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Short s2(Short value, @Cached("value") Short cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Character s3(Character value, @Cached("value") Character cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Integer s4(Integer value, @Cached("value") Integer cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Long s5(Long value, @Cached("value") Long cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Float s6(Float value, @Cached("value") Float cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        Double s7(Double value, @Cached("value") Double cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        String s8(String value, @Cached("value") String cachedValue) {
            return value;
        }

        @Specialization(guards = "value.equals(cachedValue)")
        MyClass s8(MyClass value, @Cached("value") MyClass cachedValue) {
            return value;
        }

    }

    static class MyClass {

        int equalsCalled;

        @Override
        public boolean equals(Object obj) {
            equalsCalled++;
            return super.equals(obj);
        }

        // override also hashCode to make javac happy
        @Override
        public int hashCode() {
            return super.hashCode();
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy