1 // Copyright 2011 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 #include <stdlib.h> 29 30 #include "src/v8.h" 31 32 #include "src/platform.h" 33 #include "test/cctest/cctest.h" 34 35 using namespace v8::internal; 36 37 38 TEST(Hex) { 39 UnicodeCache uc; 40 CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 41 CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 42 CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 43 CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 44 CHECK_EQ(255.0, StringToDouble(&uc, "0xff", 45 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 46 CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", 47 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 48 49 CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX)); 50 CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX)); 51 CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX)); 52 CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX)); 53 CHECK_EQ(255.0, StringToDouble(&uc, "0xff", ALLOW_HEX)); 54 CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", ALLOW_HEX)); 55 } 56 57 58 TEST(Octal) { 59 UnicodeCache uc; 60 CHECK_EQ(0.0, StringToDouble(&uc, "0o0", ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 61 CHECK_EQ(0.0, StringToDouble(&uc, "0O0", ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 62 CHECK_EQ(1.0, StringToDouble(&uc, "0o1", ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 63 CHECK_EQ(7.0, StringToDouble(&uc, "0o7", ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 64 CHECK_EQ(8.0, StringToDouble(&uc, "0o10", 65 ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 66 CHECK_EQ(63.0, StringToDouble(&uc, "0o77", 67 ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL)); 68 69 CHECK_EQ(0.0, StringToDouble(&uc, "0o0", ALLOW_OCTAL)); 70 CHECK_EQ(0.0, StringToDouble(&uc, "0O0", ALLOW_OCTAL)); 71 CHECK_EQ(1.0, StringToDouble(&uc, "0o1", ALLOW_OCTAL)); 72 CHECK_EQ(7.0, StringToDouble(&uc, "0o7", ALLOW_OCTAL)); 73 CHECK_EQ(8.0, StringToDouble(&uc, "0o10", ALLOW_OCTAL)); 74 CHECK_EQ(63.0, StringToDouble(&uc, "0o77", ALLOW_OCTAL)); 75 } 76 77 78 TEST(ImplicitOctal) { 79 UnicodeCache uc; 80 CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 81 CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 82 CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 83 CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 84 CHECK_EQ(8.0, StringToDouble(&uc, "010", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 85 CHECK_EQ(63.0, StringToDouble(&uc, "077", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 86 87 CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX)); 88 CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX)); 89 CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX)); 90 CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX)); 91 CHECK_EQ(10.0, StringToDouble(&uc, "010", ALLOW_HEX)); 92 CHECK_EQ(77.0, StringToDouble(&uc, "077", ALLOW_HEX)); 93 94 const double x = 010000000000; // Power of 2, no rounding errors. 95 CHECK_EQ(x * x * x * x * x, StringToDouble(&uc, "01" "0000000000" "0000000000" 96 "0000000000" "0000000000" "0000000000", ALLOW_IMPLICIT_OCTAL)); 97 } 98 99 100 TEST(Binary) { 101 UnicodeCache uc; 102 CHECK_EQ(0.0, StringToDouble(&uc, "0b0", 103 ALLOW_BINARY | ALLOW_IMPLICIT_OCTAL)); 104 CHECK_EQ(0.0, StringToDouble(&uc, "0B0", 105 ALLOW_BINARY | ALLOW_IMPLICIT_OCTAL)); 106 CHECK_EQ(1.0, StringToDouble(&uc, "0b1", 107 ALLOW_BINARY | ALLOW_IMPLICIT_OCTAL)); 108 CHECK_EQ(2.0, StringToDouble(&uc, "0b10", 109 ALLOW_BINARY | ALLOW_IMPLICIT_OCTAL)); 110 CHECK_EQ(3.0, StringToDouble(&uc, "0b11", 111 ALLOW_BINARY | ALLOW_IMPLICIT_OCTAL)); 112 113 CHECK_EQ(0.0, StringToDouble(&uc, "0b0", ALLOW_BINARY)); 114 CHECK_EQ(0.0, StringToDouble(&uc, "0B0", ALLOW_BINARY)); 115 CHECK_EQ(1.0, StringToDouble(&uc, "0b1", ALLOW_BINARY)); 116 CHECK_EQ(2.0, StringToDouble(&uc, "0b10", ALLOW_BINARY)); 117 CHECK_EQ(3.0, StringToDouble(&uc, "0b11", ALLOW_BINARY)); 118 } 119 120 121 TEST(MalformedOctal) { 122 UnicodeCache uc; 123 CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 124 CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 125 CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 126 127 CHECK(std::isnan(StringToDouble(&uc, "07.7", 128 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL))); 129 CHECK(std::isnan(StringToDouble(&uc, "07.8", 130 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL))); 131 CHECK(std::isnan(StringToDouble(&uc, "07e8", 132 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL))); 133 CHECK(std::isnan(StringToDouble(&uc, "07e7", 134 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL))); 135 136 CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 137 CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 138 139 CHECK_EQ(0.001, StringToDouble(&uc, "0.001", 140 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 141 CHECK_EQ(0.713, StringToDouble(&uc, "0.713", 142 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 143 144 CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX)); 145 CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX)); 146 CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX)); 147 148 CHECK_EQ(7.7, StringToDouble(&uc, "07.7", ALLOW_HEX)); 149 CHECK_EQ(7.8, StringToDouble(&uc, "07.8", ALLOW_HEX)); 150 CHECK_EQ(7e8, StringToDouble(&uc, "07e8", ALLOW_HEX)); 151 CHECK_EQ(7e7, StringToDouble(&uc, "07e7", ALLOW_HEX)); 152 153 CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX)); 154 CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX)); 155 156 CHECK_EQ(0.001, StringToDouble(&uc, "0.001", ALLOW_HEX)); 157 CHECK_EQ(0.713, StringToDouble(&uc, "0.713", ALLOW_HEX)); 158 } 159 160 161 TEST(TrailingJunk) { 162 UnicodeCache uc; 163 CHECK_EQ(8.0, StringToDouble(&uc, "8q", ALLOW_TRAILING_JUNK)); 164 CHECK_EQ(63.0, StringToDouble(&uc, "077qqq", 165 ALLOW_IMPLICIT_OCTAL | ALLOW_TRAILING_JUNK)); 166 CHECK_EQ(10.0, StringToDouble(&uc, "10e", 167 ALLOW_IMPLICIT_OCTAL | ALLOW_TRAILING_JUNK)); 168 CHECK_EQ(10.0, StringToDouble(&uc, "10e-", 169 ALLOW_IMPLICIT_OCTAL | ALLOW_TRAILING_JUNK)); 170 } 171 172 173 TEST(NonStrDecimalLiteral) { 174 UnicodeCache uc; 175 CHECK(std::isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value()))); 176 CHECK(std::isnan(StringToDouble(&uc, "", NO_FLAGS, OS::nan_value()))); 177 CHECK(std::isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value()))); 178 CHECK_EQ(0.0, StringToDouble(&uc, "", NO_FLAGS)); 179 CHECK_EQ(0.0, StringToDouble(&uc, " ", NO_FLAGS)); 180 } 181 182 183 TEST(IntegerStrLiteral) { 184 UnicodeCache uc; 185 CHECK_EQ(0.0, StringToDouble(&uc, "0.0", NO_FLAGS)); 186 CHECK_EQ(0.0, StringToDouble(&uc, "0", NO_FLAGS)); 187 CHECK_EQ(0.0, StringToDouble(&uc, "00", NO_FLAGS)); 188 CHECK_EQ(0.0, StringToDouble(&uc, "000", NO_FLAGS)); 189 CHECK_EQ(1.0, StringToDouble(&uc, "1", NO_FLAGS)); 190 CHECK_EQ(-1.0, StringToDouble(&uc, "-1", NO_FLAGS)); 191 CHECK_EQ(-1.0, StringToDouble(&uc, " -1 ", NO_FLAGS)); 192 CHECK_EQ(1.0, StringToDouble(&uc, " +1 ", NO_FLAGS)); 193 CHECK(std::isnan(StringToDouble(&uc, " - 1 ", NO_FLAGS))); 194 CHECK(std::isnan(StringToDouble(&uc, " + 1 ", NO_FLAGS))); 195 196 CHECK_EQ(0.0, StringToDouble(&uc, "0e0", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 197 CHECK_EQ(0.0, StringToDouble(&uc, "0e1", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 198 CHECK_EQ(0.0, StringToDouble(&uc, "0e-1", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 199 CHECK_EQ(0.0, StringToDouble(&uc, "0e-100000", 200 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 201 CHECK_EQ(0.0, StringToDouble(&uc, "0e+100000", 202 ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 203 CHECK_EQ(0.0, StringToDouble(&uc, "0.", ALLOW_HEX | ALLOW_IMPLICIT_OCTAL)); 204 } 205 206 207 TEST(LongNumberStr) { 208 UnicodeCache uc; 209 CHECK_EQ(1e10, StringToDouble(&uc, "1" "0000000000", NO_FLAGS)); 210 CHECK_EQ(1e20, StringToDouble(&uc, "1" "0000000000" "0000000000", NO_FLAGS)); 211 212 CHECK_EQ(1e60, StringToDouble(&uc, "1" "0000000000" "0000000000" "0000000000" 213 "0000000000" "0000000000" "0000000000", NO_FLAGS)); 214 215 CHECK_EQ(1e-2, StringToDouble(&uc, "." "0" "1", NO_FLAGS)); 216 CHECK_EQ(1e-11, StringToDouble(&uc, "." "0000000000" "1", NO_FLAGS)); 217 CHECK_EQ(1e-21, StringToDouble(&uc, "." "0000000000" "0000000000" "1", 218 NO_FLAGS)); 219 220 CHECK_EQ(1e-61, StringToDouble(&uc, "." "0000000000" "0000000000" "0000000000" 221 "0000000000" "0000000000" "0000000000" "1", NO_FLAGS)); 222 223 224 // x = 24414062505131248.0 and y = 24414062505131252.0 are representable in 225 // double. Check chat z = (x + y) / 2 is rounded to x... 226 CHECK_EQ(24414062505131248.0, 227 StringToDouble(&uc, "24414062505131250.0", NO_FLAGS)); 228 229 // ... and z = (x + y) / 2 + delta is rounded to y. 230 CHECK_EQ(24414062505131252.0, 231 StringToDouble(&uc, "24414062505131250.000000001", NO_FLAGS)); 232 } 233 234 235 TEST(MaximumSignificantDigits) { 236 UnicodeCache uc; 237 char num[] = 238 "4.4501477170144020250819966727949918635852426585926051135169509" 239 "122872622312493126406953054127118942431783801370080830523154578" 240 "251545303238277269592368457430440993619708911874715081505094180" 241 "604803751173783204118519353387964161152051487413083163272520124" 242 "606023105869053620631175265621765214646643181420505164043632222" 243 "668006474326056011713528291579642227455489682133472873831754840" 244 "341397809846934151055619529382191981473003234105366170879223151" 245 "087335413188049110555339027884856781219017754500629806224571029" 246 "581637117459456877330110324211689177656713705497387108207822477" 247 "584250967061891687062782163335299376138075114200886249979505279" 248 "101870966346394401564490729731565935244123171539810221213221201" 249 "847003580761626016356864581135848683152156368691976240370422601" 250 "6998291015625000000000000000000000000000000000e-308"; 251 252 CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS)); 253 254 // Changes the result of strtod (at least in glibc implementation). 255 num[sizeof(num) - 8] = '1'; 256 257 CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS)); 258 } 259 260 261 TEST(MinimumExponent) { 262 UnicodeCache uc; 263 // Same test but with different point-position. 264 char num[] = 265 "445014771701440202508199667279499186358524265859260511351695091" 266 "228726223124931264069530541271189424317838013700808305231545782" 267 "515453032382772695923684574304409936197089118747150815050941806" 268 "048037511737832041185193533879641611520514874130831632725201246" 269 "060231058690536206311752656217652146466431814205051640436322226" 270 "680064743260560117135282915796422274554896821334728738317548403" 271 "413978098469341510556195293821919814730032341053661708792231510" 272 "873354131880491105553390278848567812190177545006298062245710295" 273 "816371174594568773301103242116891776567137054973871082078224775" 274 "842509670618916870627821633352993761380751142008862499795052791" 275 "018709663463944015644907297315659352441231715398102212132212018" 276 "470035807616260163568645811358486831521563686919762403704226016" 277 "998291015625000000000000000000000000000000000e-1108"; 278 279 CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS)); 280 281 // Changes the result of strtod (at least in glibc implementation). 282 num[sizeof(num) - 8] = '1'; 283 284 CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS)); 285 } 286 287 288 TEST(MaximumExponent) { 289 UnicodeCache uc; 290 char num[] = "0.16e309"; 291 292 CHECK_EQ(1.59999999999999997765e+308, StringToDouble(&uc, num, NO_FLAGS)); 293 } 294 295 296 TEST(ExponentNumberStr) { 297 UnicodeCache uc; 298 CHECK_EQ(1e1, StringToDouble(&uc, "1e1", NO_FLAGS)); 299 CHECK_EQ(1e1, StringToDouble(&uc, "1e+1", NO_FLAGS)); 300 CHECK_EQ(1e-1, StringToDouble(&uc, "1e-1", NO_FLAGS)); 301 CHECK_EQ(1e100, StringToDouble(&uc, "1e+100", NO_FLAGS)); 302 CHECK_EQ(1e-100, StringToDouble(&uc, "1e-100", NO_FLAGS)); 303 CHECK_EQ(1e-106, StringToDouble(&uc, ".000001e-100", NO_FLAGS)); 304 } 305 306 307 class OneBit1: public BitField<uint32_t, 0, 1> {}; 308 class OneBit2: public BitField<uint32_t, 7, 1> {}; 309 class EightBit1: public BitField<uint32_t, 0, 8> {}; 310 class EightBit2: public BitField<uint32_t, 13, 8> {}; 311 312 TEST(BitField) { 313 uint32_t x; 314 315 // One bit bit field can hold values 0 and 1. 316 CHECK(!OneBit1::is_valid(static_cast<uint32_t>(-1))); 317 CHECK(!OneBit2::is_valid(static_cast<uint32_t>(-1))); 318 for (int i = 0; i < 2; i++) { 319 CHECK(OneBit1::is_valid(i)); 320 x = OneBit1::encode(i); 321 CHECK_EQ(i, OneBit1::decode(x)); 322 323 CHECK(OneBit2::is_valid(i)); 324 x = OneBit2::encode(i); 325 CHECK_EQ(i, OneBit2::decode(x)); 326 } 327 CHECK(!OneBit1::is_valid(2)); 328 CHECK(!OneBit2::is_valid(2)); 329 330 // Eight bit bit field can hold values from 0 tp 255. 331 CHECK(!EightBit1::is_valid(static_cast<uint32_t>(-1))); 332 CHECK(!EightBit2::is_valid(static_cast<uint32_t>(-1))); 333 for (int i = 0; i < 256; i++) { 334 CHECK(EightBit1::is_valid(i)); 335 x = EightBit1::encode(i); 336 CHECK_EQ(i, EightBit1::decode(x)); 337 CHECK(EightBit2::is_valid(i)); 338 x = EightBit2::encode(i); 339 CHECK_EQ(i, EightBit2::decode(x)); 340 } 341 CHECK(!EightBit1::is_valid(256)); 342 CHECK(!EightBit2::is_valid(256)); 343 } 344 345 346 class UpperBits: public BitField64<int, 61, 3> {}; 347 class MiddleBits: public BitField64<int, 31, 2> {}; 348 349 TEST(BitField64) { 350 uint64_t x; 351 352 // Test most significant bits. 353 x = V8_2PART_UINT64_C(0xE0000000, 00000000); 354 CHECK(x == UpperBits::encode(7)); 355 CHECK_EQ(7, UpperBits::decode(x)); 356 357 // Test the 32/64-bit boundary bits. 358 x = V8_2PART_UINT64_C(0x00000001, 80000000); 359 CHECK(x == MiddleBits::encode(3)); 360 CHECK_EQ(3, MiddleBits::decode(x)); 361 } 362