Ben Murdoch | 69a99ed | 2011-11-30 16:03:39 +0000 | [diff] [blame] | 1 | // Copyright 2011 the V8 project authors. All rights reserved. |
Leon Clarke | 4515c47 | 2010-02-03 11:58:03 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 28 | // Flags: --allow-natives-syntax |
Leon Clarke | 4515c47 | 2010-02-03 11:58:03 +0000 | [diff] [blame] | 29 | |
Ben Murdoch | 69a99ed | 2011-11-30 16:03:39 +0000 | [diff] [blame] | 30 | var test_id = 0; |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 31 | function testRound(expect, input) { |
Ben Murdoch | 69a99ed | 2011-11-30 16:03:39 +0000 | [diff] [blame] | 32 | // Make source code different on each invocation to make |
| 33 | // sure it gets optimized each time. |
| 34 | var doRound = new Function('input', |
| 35 | '"' + (test_id++) + '";return Math.round(input)'); |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 36 | assertEquals(expect, doRound(input)); |
| 37 | assertEquals(expect, doRound(input)); |
| 38 | assertEquals(expect, doRound(input)); |
| 39 | %OptimizeFunctionOnNextCall(doRound); |
| 40 | assertEquals(expect, doRound(input)); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 41 | |
| 42 | // Force the Math.round() representation to double to exercise the associated |
| 43 | // optimized code. |
| 44 | var doRoundToDouble = new Function('input', |
| 45 | '"' + (test_id++) + '";return Math.round(input) + -0.0'); |
| 46 | assertEquals(expect, doRoundToDouble(input)); |
| 47 | assertEquals(expect, doRoundToDouble(input)); |
| 48 | assertEquals(expect, doRoundToDouble(input)); |
| 49 | %OptimizeFunctionOnNextCall(doRoundToDouble); |
| 50 | assertEquals(expect, doRoundToDouble(input)); |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 51 | } |
Leon Clarke | 4515c47 | 2010-02-03 11:58:03 +0000 | [diff] [blame] | 52 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 53 | testRound(0, 0); |
| 54 | testRound(-0, -0); |
| 55 | testRound(Infinity, Infinity); |
| 56 | testRound(-Infinity, -Infinity); |
| 57 | testRound(NaN, NaN); |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 58 | |
Ben Murdoch | 69a99ed | 2011-11-30 16:03:39 +0000 | [diff] [blame] | 59 | // Regression test for a bug where a negative zero coming from Math.round |
| 60 | // was not properly handled by other operations. |
| 61 | function roundsum(i, n) { |
| 62 | var ret = Math.round(n); |
| 63 | while (--i > 0) { |
| 64 | ret += Math.round(n); |
| 65 | } |
| 66 | return ret; |
| 67 | } |
| 68 | assertEquals(-0, roundsum(1, -0)); |
| 69 | %OptimizeFunctionOnNextCall(roundsum); |
| 70 | // The optimized function will deopt. Run it with enough iterations to try |
| 71 | // to optimize via OSR (triggering the bug). |
| 72 | assertEquals(-0, roundsum(100000, -0)); |
| 73 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 74 | testRound(1, 0.5); |
| 75 | testRound(1, 0.7); |
| 76 | testRound(1, 1); |
| 77 | testRound(1, 1.1); |
| 78 | testRound(1, 1.49999); |
| 79 | testRound(-0, -0.5); |
| 80 | testRound(-1, -0.5000000000000001); |
| 81 | testRound(-1, -0.7); |
| 82 | testRound(-1, -1); |
| 83 | testRound(-1, -1.1); |
| 84 | testRound(-1, -1.49999); |
| 85 | testRound(-1, -1.5); |
| 86 | |
| 87 | testRound(9007199254740990, 9007199254740990); |
| 88 | testRound(9007199254740991, 9007199254740991); |
| 89 | testRound(-9007199254740990, -9007199254740990); |
| 90 | testRound(-9007199254740991, -9007199254740991); |
| 91 | testRound(Number.MAX_VALUE, Number.MAX_VALUE); |
| 92 | testRound(-Number.MAX_VALUE, -Number.MAX_VALUE); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 93 | testRound(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); |
| 94 | testRound(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 1); |
| 95 | testRound(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 2); |
| 96 | testRound(Number.MAX_SAFE_INTEGER + 3, Number.MAX_SAFE_INTEGER + 3); |
| 97 | testRound(Number.MAX_SAFE_INTEGER + 4, Number.MAX_SAFE_INTEGER + 4); |
| 98 | testRound(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); |
| 99 | testRound(Number.MIN_SAFE_INTEGER - 1, Number.MIN_SAFE_INTEGER - 1); |
| 100 | testRound(Number.MIN_SAFE_INTEGER - 2, Number.MIN_SAFE_INTEGER - 2); |
| 101 | testRound(Number.MIN_SAFE_INTEGER - 3, Number.MIN_SAFE_INTEGER - 3); |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 102 | |
| 103 | testRound(536870911, 536870910.5); |
| 104 | testRound(536870911, 536870911); |
| 105 | testRound(536870911, 536870911.4); |
| 106 | testRound(536870912, 536870911.5); |
| 107 | testRound(536870912, 536870912); |
| 108 | testRound(536870912, 536870912.4); |
| 109 | testRound(536870913, 536870912.5); |
| 110 | testRound(536870913, 536870913); |
| 111 | testRound(536870913, 536870913.4); |
| 112 | testRound(1073741823, 1073741822.5); |
| 113 | testRound(1073741823, 1073741823); |
| 114 | testRound(1073741823, 1073741823.4); |
| 115 | testRound(1073741824, 1073741823.5); |
| 116 | testRound(1073741824, 1073741824); |
| 117 | testRound(1073741824, 1073741824.4); |
| 118 | testRound(1073741825, 1073741824.5); |
| 119 | testRound(2147483647, 2147483646.5); |
| 120 | testRound(2147483647, 2147483647); |
| 121 | testRound(2147483647, 2147483647.4); |
| 122 | testRound(2147483648, 2147483647.5); |
| 123 | testRound(2147483648, 2147483648); |
| 124 | testRound(2147483648, 2147483648.4); |
| 125 | testRound(2147483649, 2147483648.5); |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 126 | |
| 127 | // Tests based on WebKit LayoutTests |
| 128 | |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 129 | testRound(0, 0.4); |
| 130 | testRound(-0, -0.4); |
| 131 | testRound(-0, -0.5); |
| 132 | testRound(1, 0.6); |
| 133 | testRound(-1, -0.6); |
| 134 | testRound(2, 1.5); |
| 135 | testRound(2, 1.6); |
| 136 | testRound(-2, -1.6); |
| 137 | testRound(8640000000000000, 8640000000000000); |
| 138 | testRound(8640000000000001, 8640000000000001); |
| 139 | testRound(8640000000000002, 8640000000000002); |
| 140 | testRound(9007199254740990, 9007199254740990); |
| 141 | testRound(9007199254740991, 9007199254740991); |
| 142 | testRound(1.7976931348623157e+308, 1.7976931348623157e+308); |
| 143 | testRound(-8640000000000000, -8640000000000000); |
| 144 | testRound(-8640000000000001, -8640000000000001); |
| 145 | testRound(-8640000000000002, -8640000000000002); |
| 146 | testRound(-9007199254740990, -9007199254740990); |
| 147 | testRound(-9007199254740991, -9007199254740991); |
| 148 | testRound(-1.7976931348623157e+308, -1.7976931348623157e+308); |
| 149 | testRound(Infinity, Infinity); |
| 150 | testRound(-Infinity, -Infinity); |
| 151 | |
| 152 | // Some special double number cases. |
| 153 | var ulp = Math.pow(2, -1022 - 52); |
| 154 | var max_denormal = (Math.pow(2, 52) - 1) * ulp; |
| 155 | var min_normal = Math.pow(2, -1022); |
| 156 | var max_fraction = Math.pow(2, 52) - 0.5; |
| 157 | var min_nonfraction = Math.pow(2, 52); |
| 158 | var max_non_infinite = Number.MAX_VALUE; |
| 159 | |
| 160 | var max_smi31 = Math.pow(2,30) - 1; |
| 161 | var min_smi31 = -Math.pow(2,30); |
| 162 | var max_smi32 = Math.pow(2,31) - 1; |
| 163 | var min_smi32 = -Math.pow(2,31); |
| 164 | |
| 165 | testRound(0, ulp); |
| 166 | testRound(0, max_denormal); |
| 167 | testRound(0, min_normal); |
| 168 | testRound(0, 0.49999999999999994); |
| 169 | testRound(1, 0.5); |
| 170 | testRound(Math.pow(2,52), max_fraction); |
| 171 | testRound(min_nonfraction, min_nonfraction); |
| 172 | testRound(max_non_infinite, max_non_infinite); |
| 173 | |
| 174 | testRound(max_smi31, max_smi31 - 0.5); |
| 175 | testRound(max_smi31 + 1, max_smi31 + 0.5); |
| 176 | testRound(max_smi32, max_smi32 - 0.5); |
| 177 | testRound(max_smi32 + 1, max_smi32 + 0.5); |
| 178 | |
| 179 | testRound(-0, -ulp); |
| 180 | testRound(-0, -max_denormal); |
| 181 | testRound(-0, -min_normal); |
| 182 | testRound(-0, -0.49999999999999994); |
| 183 | testRound(-0, -0.5); |
| 184 | testRound(-Math.pow(2,52)+1, -max_fraction); |
| 185 | testRound(-min_nonfraction, -min_nonfraction); |
| 186 | testRound(-max_non_infinite, -max_non_infinite); |
| 187 | |
| 188 | testRound(min_smi31, min_smi31 - 0.5); |
| 189 | testRound(min_smi31 + 1, min_smi31 + 0.5); |
| 190 | testRound(min_smi32, min_smi32 - 0.5); |
| 191 | testRound(min_smi32 + 1, min_smi32 + 0.5); |