nashorn/test/script/basic/JDK-8035712.js
changeset 29283 fb47e4d25a9f
child 31925 85c87bc2f1f3
equal deleted inserted replaced
29282:a8523237b66c 29283:fb47e4d25a9f
       
     1 /*
       
     2  * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  * 
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  * 
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  * 
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  * 
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /**
       
    25  * JDK-8035712: Restore some of the RuntimeCallSite specializations
       
    26  *
       
    27  * @test
       
    28  * @run
       
    29  */
       
    30 
       
    31 if ((typeof Assert) == "undefined") {
       
    32     Assert = { 
       
    33         assertTrue: function(x) { if(!x) { throw "expected true" } },
       
    34         assertFalse: function(x) { if(x) { throw "expected false" } },
       
    35     };
       
    36 }
       
    37 
       
    38 function nop() {}
       
    39 
       
    40 function EQ(x, y) {
       
    41     // Exercise normal evaluation
       
    42     Assert.assertTrue (x == y);
       
    43     Assert.assertTrue (y == x);
       
    44     Assert.assertFalse(x != y);
       
    45     Assert.assertFalse(y != x);
       
    46     // Exercise the branch optimizer
       
    47     if (x == y) { nop(); } else { Assert.fail(); }
       
    48     if (y == x) { nop(); } else { Assert.fail(); }
       
    49     if (x != y) { Assert.fail(); } else { nop(); }
       
    50     if (y != x) { Assert.fail(); } else { nop(); }
       
    51 }
       
    52 
       
    53 function NE(x, y) {
       
    54     // Exercise normal evaluation
       
    55     Assert.assertTrue (x != y);
       
    56     Assert.assertTrue (y != x);
       
    57     Assert.assertFalse(x == y);
       
    58     Assert.assertFalse(y == x);
       
    59     // Exercise the branch optimizer
       
    60     if (x != y) { nop(); } else { Assert.fail(); }
       
    61     if (y != x) { nop(); } else { Assert.fail(); }
       
    62     if (x == y) { Assert.fail(); } else { nop(); }
       
    63     if (y == x) { Assert.fail(); } else { nop(); }
       
    64 }
       
    65 
       
    66 function STRICT_EQ(x, y) {
       
    67     // Exercise normal evaluation
       
    68     Assert.assertTrue (x === y);
       
    69     Assert.assertTrue (y === x);
       
    70     Assert.assertFalse(x !== y);
       
    71     Assert.assertFalse(y !== x);
       
    72     // Exercise the branch optimizer
       
    73     if (x === y) { nop(); } else { Assert.fail(); }
       
    74     if (y === x) { nop(); } else { Assert.fail(); }
       
    75     if (x !== y) { Assert.fail(); } else { nop(); }
       
    76     if (y !== x) { Assert.fail(); } else { nop(); }
       
    77 }
       
    78 
       
    79 function STRICT_NE(x, y) {
       
    80     // Exercise normal evaluation
       
    81     Assert.assertTrue (x !== y);
       
    82     Assert.assertTrue (y !== x);
       
    83     Assert.assertFalse(x === y);
       
    84     Assert.assertFalse(y === x);
       
    85     // Exercise the branch optimizer
       
    86     if (x !== y) { nop(); } else { Assert.fail(); }
       
    87     if (y !== x) { nop(); } else { Assert.fail(); }
       
    88     if (x === y) { Assert.fail(); } else { nop(); }
       
    89     if (y === x) { Assert.fail(); } else { nop(); }
       
    90 }
       
    91 
       
    92 function cmpToAnyNumber(cmp, value) {
       
    93     cmp(1, value);
       
    94     cmp(4294967296, value);
       
    95     cmp(1.2, value);
       
    96     cmp(Infinity, value);
       
    97     cmp(-Infinity, value);
       
    98     cmp(1/Infinity, value);
       
    99     cmp(0, value);
       
   100     cmp(-0, value);
       
   101     cmp(true, value);
       
   102     cmp(false, value);
       
   103 }
       
   104 
       
   105 function notEqualToAnyNumber(value) {
       
   106     cmpToAnyNumber(NE, value);
       
   107     cmpToAnyNumber(STRICT_NE, value);
       
   108 }
       
   109 
       
   110 notEqualToAnyNumber(null);
       
   111 notEqualToAnyNumber(void 0);
       
   112 notEqualToAnyNumber("abc");
       
   113 notEqualToAnyNumber({});
       
   114 notEqualToAnyNumber(["xyz"]);
       
   115 
       
   116 function objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) {
       
   117     var obj = {
       
   118         count: 0
       
   119     };
       
   120     obj[fnName] = function() { this.count++; return "foo"; };
       
   121     notEqualToAnyNumber(obj);
       
   122     // Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons
       
   123     // STRICT_NE doesn't invoke toString.
       
   124     Assert.assertTrue(80 === obj.count);
       
   125 }
       
   126 objectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf");
       
   127 objectWithPrimitiveFunctionNotEqualToAnyNumber("toString");
       
   128 
       
   129 function objectEqualButNotStrictlyEqual(val, obj) {
       
   130     EQ(val, obj);
       
   131     STRICT_NE(val, obj);
       
   132 }
       
   133 
       
   134 function numberEqualButNotStrictlyEqualToObject(num, obj) {
       
   135     objectEqualButNotStrictlyEqual(num, obj);
       
   136     objectEqualButNotStrictlyEqual(num, [obj]);
       
   137     objectEqualButNotStrictlyEqual(num, [[obj]]);
       
   138 }
       
   139 
       
   140 function numberEqualButNotStrictlyEqualToZeroObjects(num) {
       
   141     numberEqualButNotStrictlyEqualToObject(num, [0]);
       
   142     numberEqualButNotStrictlyEqualToObject(num, "");
       
   143     numberEqualButNotStrictlyEqualToObject(num, []);
       
   144     numberEqualButNotStrictlyEqualToObject(num, "0");
       
   145 }
       
   146 
       
   147 numberEqualButNotStrictlyEqualToZeroObjects(0);
       
   148 numberEqualButNotStrictlyEqualToZeroObjects(1/Infinity);
       
   149 numberEqualButNotStrictlyEqualToZeroObjects(false);
       
   150 
       
   151 function numberEqualButNotStrictlyEqualToObjectEquivalent(num) {
       
   152     var str = String(num);
       
   153     objectEqualButNotStrictlyEqual(num, str);
       
   154     objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return str }});
       
   155     objectEqualButNotStrictlyEqual(num, { toString: function() { return str }});
       
   156     objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return num }});
       
   157     objectEqualButNotStrictlyEqual(num, { toString: function() { return num }});
       
   158 }
       
   159 
       
   160 numberEqualButNotStrictlyEqualToObjectEquivalent(1);
       
   161 numberEqualButNotStrictlyEqualToObjectEquivalent(4294967296);
       
   162 numberEqualButNotStrictlyEqualToObjectEquivalent(1.2);
       
   163 numberEqualButNotStrictlyEqualToObjectEquivalent(Infinity);
       
   164 numberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity);
       
   165 numberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity);
       
   166 numberEqualButNotStrictlyEqualToObjectEquivalent(0);
       
   167 numberEqualButNotStrictlyEqualToObjectEquivalent(-0);
       
   168 
       
   169 STRICT_EQ(1, new java.lang.Integer(1));
       
   170 STRICT_EQ(1, new java.lang.Double(1));
       
   171 STRICT_EQ(1.2, new java.lang.Double(1.2));
       
   172 
       
   173 function LE(x, y) {
       
   174     // Exercise normal evaluation
       
   175     Assert.assertTrue(x <= y);
       
   176     Assert.assertTrue(y >= x);
       
   177     Assert.assertFalse(x > y);
       
   178     Assert.assertFalse(x < y);
       
   179     // Exercise the branch optimizer
       
   180     if (x <= y) { nop(); } else { Assert.fail(); }
       
   181     if (y >= x) { nop(); } else { Assert.fail(); }
       
   182     if (x > y) { Assert.fail(); } else { nop(); }
       
   183     if (y < x) { Assert.fail(); } else { nop(); }
       
   184 }
       
   185 
       
   186 function mutuallyLessThanOrEqual(x, y) {
       
   187     LE(x, y);
       
   188     LE(y, x);
       
   189 }
       
   190 
       
   191 mutuallyLessThanOrEqual(0, null);
       
   192 mutuallyLessThanOrEqual(false, null);
       
   193 mutuallyLessThanOrEqual(1/Infinity, null);
       
   194 
       
   195 function mutuallyLessThanEqualToObjectWithValue(num, val) {
       
   196     mutuallyLessThanOrEqual(num, { valueOf: function() { return val } });
       
   197     mutuallyLessThanOrEqual(num, { toString: function() { return val } });
       
   198 }
       
   199 
       
   200 mutuallyLessThanEqualToObjectWithValue(false, 0);
       
   201 mutuallyLessThanEqualToObjectWithValue(false, "");
       
   202 
       
   203 mutuallyLessThanEqualToObjectWithValue(true, 1);
       
   204 mutuallyLessThanEqualToObjectWithValue(true, "1");
       
   205 
       
   206 function lessThanEqualToObjectEquivalent(num) {
       
   207     var str = String(num);
       
   208     mutuallyLessThanOrEqual(num, str);
       
   209     mutuallyLessThanEqualToObjectWithValue(num, num);
       
   210     mutuallyLessThanEqualToObjectWithValue(num, str);
       
   211 }
       
   212 
       
   213 lessThanEqualToObjectEquivalent(1);
       
   214 lessThanEqualToObjectEquivalent(4294967296);
       
   215 lessThanEqualToObjectEquivalent(1.2);
       
   216 lessThanEqualToObjectEquivalent(Infinity);
       
   217 lessThanEqualToObjectEquivalent(-Infinity);
       
   218 lessThanEqualToObjectEquivalent(1/Infinity);
       
   219 lessThanEqualToObjectEquivalent(0);
       
   220 lessThanEqualToObjectEquivalent(-0);
       
   221 
       
   222 function INCOMPARABLE(x, y) {
       
   223     // Exercise normal evaluation
       
   224     Assert.assertFalse(x < y);
       
   225     Assert.assertFalse(x > y);
       
   226     Assert.assertFalse(x <= y);
       
   227     Assert.assertFalse(x >= y);
       
   228     Assert.assertFalse(y < x);
       
   229     Assert.assertFalse(y > x);
       
   230     Assert.assertFalse(y <= x);
       
   231     Assert.assertFalse(y >= x);
       
   232     // Exercise the branch optimizer
       
   233     if (x < y) { Assert.fail(); } else { nop(); }
       
   234     if (x > y) { Assert.fail(); } else { nop(); }
       
   235     if (x <= y) { Assert.fail(); } else { nop(); }
       
   236     if (x >= y) { Assert.fail(); } else { nop(); }
       
   237     if (y < x) { Assert.fail(); } else { nop(); }
       
   238     if (y > x) { Assert.fail(); } else { nop(); }
       
   239     if (y <= x) { Assert.fail(); } else { nop(); }
       
   240     if (y >= x) { Assert.fail(); } else { nop(); }
       
   241 }
       
   242 
       
   243 function isIncomparable(value) {
       
   244     cmpToAnyNumber(INCOMPARABLE, value);
       
   245 }
       
   246 
       
   247 isIncomparable(void 0);
       
   248 isIncomparable({ valueOf: function() { return NaN }});
       
   249 isIncomparable({ toString: function() { return NaN }});
       
   250 
       
   251 // Force ScriptRuntime.LT(Object, Object) etc. comparisons
       
   252 function cmpObj(fn, x, y) {
       
   253     fn({valueOf: function() { return x }}, {valueOf: function() { return y }});
       
   254 }
       
   255 
       
   256 function LT(x, y) {
       
   257     Assert.assertTrue(x < y);
       
   258     Assert.assertTrue(y > x);
       
   259     Assert.assertFalse(x >= y);
       
   260     Assert.assertFalse(y <= x);
       
   261 }
       
   262 
       
   263 cmpObj(LT, 1, 2);
       
   264 cmpObj(LT, 1, "2");
       
   265 cmpObj(LT, "1", 2);
       
   266 cmpObj(LT, "a", "b");
       
   267 cmpObj(LT, -Infinity, 0);
       
   268 cmpObj(LT, 0, Infinity);
       
   269 cmpObj(LT, -Infinity, Infinity);
       
   270 cmpObj(INCOMPARABLE, 1, NaN);
       
   271 cmpObj(INCOMPARABLE, NaN, NaN);
       
   272 cmpObj(INCOMPARABLE, "boo", NaN);
       
   273 cmpObj(INCOMPARABLE, 1, "boo"); // boo number value will be NaN
       
   274 
       
   275 // Test that a comparison call site can deoptimize from (int, int) to (object, object)
       
   276 (function(){
       
   277     var x = [1,  2,  "a"];
       
   278     var y = [2, "3", "b"];
       
   279     for(var i = 0; i < 3; ++i) {
       
   280         Assert.assertTrue(x[i] < y[i]);
       
   281     }
       
   282 })();