1// Copyright 2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28// Flags: --allow-natives-syntax 29 30// Test Math.min(). 31 32assertEquals(Infinity, Math.min()); 33assertEquals(1, Math.min(1)); 34assertEquals(1, Math.min(1, 2)); 35assertEquals(1, Math.min(2, 1)); 36assertEquals(1, Math.min(1, 2, 3)); 37assertEquals(1, Math.min(3, 2, 1)); 38assertEquals(1, Math.min(2, 3, 1)); 39assertEquals(1.1, Math.min(1.1, 2.2, 3.3)); 40assertEquals(1.1, Math.min(3.3, 2.2, 1.1)); 41assertEquals(1.1, Math.min(2.2, 3.3, 1.1)); 42 43// Prepare a non-Smi zero value. 44function returnsNonSmi(){ return 0.25; } 45var ZERO = (function() { 46 var z; 47 // We have to have a loop here because the first time we get a Smi from the 48 // runtime system. After a while the binary op IC settles down and we get 49 // a non-Smi from the generated code. 50 for (var i = 0; i < 10; i++) { 51 z = returnsNonSmi() - returnsNonSmi(); 52 } 53 return z; 54})(); 55assertEquals(0, ZERO); 56assertEquals(Infinity, 1/ZERO); 57assertEquals(-Infinity, 1/-ZERO); 58// Here we would like to have assertFalse(%_IsSmi(ZERO)); This is, however, 59// unreliable, since a new space exhaustion at a critical moment could send 60// us into the runtime system, which would quite legitimately put a Smi zero 61// here. 62assertFalse(%_IsSmi(-ZERO)); 63 64var o = {}; 65o.valueOf = function() { return 1; }; 66assertEquals(1, Math.min(2, 3, '1')); 67assertEquals(1, Math.min(3, o, 2)); 68assertEquals(1, Math.min(o, 2)); 69assertEquals(-Infinity, Infinity / Math.min(-0, +0)); 70assertEquals(-Infinity, Infinity / Math.min(+0, -0)); 71assertEquals(-Infinity, Infinity / Math.min(+0, -0, 1)); 72assertEquals(-Infinity, Infinity / Math.min(-0, ZERO)); 73assertEquals(-Infinity, Infinity / Math.min(ZERO, -0)); 74assertEquals(-Infinity, Infinity / Math.min(ZERO, -0, 1)); 75assertEquals(-1, Math.min(+0, -0, -1)); 76assertEquals(-1, Math.min(-1, +0, -0)); 77assertEquals(-1, Math.min(+0, -1, -0)); 78assertEquals(-1, Math.min(-0, -1, +0)); 79assertEquals(NaN, Math.min('oxen')); 80assertEquals(NaN, Math.min('oxen', 1)); 81assertEquals(NaN, Math.min(1, 'oxen')); 82 83 84// Test Math.max(). 85 86assertEquals(Number.NEGATIVE_INFINITY, Math.max()); 87assertEquals(1, Math.max(1)); 88assertEquals(2, Math.max(1, 2)); 89assertEquals(2, Math.max(2, 1)); 90assertEquals(3, Math.max(1, 2, 3)); 91assertEquals(3, Math.max(3, 2, 1)); 92assertEquals(3, Math.max(2, 3, 1)); 93assertEquals(3.3, Math.max(1.1, 2.2, 3.3)); 94assertEquals(3.3, Math.max(3.3, 2.2, 1.1)); 95assertEquals(3.3, Math.max(2.2, 3.3, 1.1)); 96 97var o = {}; 98o.valueOf = function() { return 3; }; 99assertEquals(3, Math.max(2, '3', 1)); 100assertEquals(3, Math.max(1, o, 2)); 101assertEquals(3, Math.max(o, 1)); 102assertEquals(Infinity, Infinity / Math.max(-0, +0)); 103assertEquals(Infinity, Infinity / Math.max(+0, -0)); 104assertEquals(Infinity, Infinity / Math.max(+0, -0, -1)); 105assertEquals(Infinity, Infinity / Math.max(-0, ZERO)); 106assertEquals(Infinity, Infinity / Math.max(ZERO, -0)); 107assertEquals(Infinity, Infinity / Math.max(ZERO, -0, -1)); 108assertEquals(1, Math.max(+0, -0, +1)); 109assertEquals(1, Math.max(+1, +0, -0)); 110assertEquals(1, Math.max(+0, +1, -0)); 111assertEquals(1, Math.max(-0, +1, +0)); 112assertEquals(NaN, Math.max('oxen')); 113assertEquals(NaN, Math.max('oxen', 1)); 114assertEquals(NaN, Math.max(1, 'oxen')); 115 116assertEquals(Infinity, 1/Math.max(ZERO, -0)); 117assertEquals(Infinity, 1/Math.max(-0, ZERO)); 118 119function run(crankshaft_test) { 120 crankshaft_test(1); 121 crankshaft_test(1); 122 %OptimizeFunctionOnNextCall(crankshaft_test); 123 crankshaft_test(-0); 124} 125 126function crankshaft_test_1(arg) { 127 var v1 = 1; 128 var v2 = 5; 129 var v3 = 1.5; 130 var v4 = 5.5; 131 var v5 = 2; 132 var v6 = 6; 133 var v7 = 0; 134 var v8 = -0; 135 136 var v9 = 9.9; 137 var v0 = 10.1; 138 // Integer32 representation. 139 assertEquals(v2, Math.max(v1++, v2++)); 140 assertEquals(v1, Math.min(v1++, v2++)); 141 // Tagged representation. 142 assertEquals(v4, Math.max(v3, v4)); 143 assertEquals(v3, Math.min(v3, v4)); 144 assertEquals(v6, Math.max(v5, v6)); 145 assertEquals(v5, Math.min(v5, v6)); 146 // Double representation. 147 assertEquals(v0, Math.max(v0++, v9++)); 148 assertEquals(v9, Math.min(v0++, v9++)); 149 // Mixed representation. 150 assertEquals(v1, Math.min(v1++, v9++)); // int32, double 151 assertEquals(v0, Math.max(v0++, v2++)); // double, int32 152 assertEquals(v1, Math.min(v1++, v6)); // int32, tagged 153 assertEquals(v2, Math.max(v5, v2++)); // tagged, int32 154 assertEquals(v6, Math.min(v6, v9++)); // tagged, double 155 assertEquals(v0, Math.max(v0++, v5)); // double, tagged 156 157 // Minus zero. 158 assertEquals(Infinity, 1/Math.max(v7, v8)); 159 assertEquals(-Infinity, 1/Math.min(v7, v8)); 160 // NaN. 161 assertEquals(NaN, Math.max(NaN, v8)); 162 assertEquals(NaN, Math.min(NaN, v9)); 163 assertEquals(NaN, Math.max(v8, NaN)); 164 assertEquals(NaN, Math.min(v9, NaN)); 165 // Minus zero as Integer32. 166 assertEquals((arg === -0) ? -Infinity : 1, 1/Math.min(arg, v2)); 167} 168 169run(crankshaft_test_1); 170 171function crankshaft_test_2() { 172 var v9 = {}; 173 v9.valueOf = function() { return 6; } 174 // Deopt expected due to non-heapnumber objects. 175 assertEquals(6, Math.min(v9, 12)); 176} 177 178run(crankshaft_test_2); 179 180// Test overriding Math.min and Math.max 181Math.min = function(a, b) { return a + b; } 182Math.max = function(a, b) { return a - b; } 183 184function crankshaft_test_3() { 185 assertEquals(8, Math.min(3, 5)); 186 assertEquals(3, Math.max(5, 2)); 187} 188 189run(crankshaft_test_3); 190