1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/v8.h" 6 7 #include "test/cctest/compiler/function-tester.h" 8 9 using namespace v8::internal; 10 using namespace v8::internal::compiler; 11 12 TEST(BinopAdd) { 13 FunctionTester T("(function(a,b) { return a + b; })"); 14 15 T.CheckCall(3, 1, 2); 16 T.CheckCall(-11, -2, -9); 17 T.CheckCall(-11, -1.5, -9.5); 18 T.CheckCall(T.Val("AB"), T.Val("A"), T.Val("B")); 19 T.CheckCall(T.Val("A11"), T.Val("A"), T.Val(11)); 20 T.CheckCall(T.Val("12B"), T.Val(12), T.Val("B")); 21 T.CheckCall(T.Val("38"), T.Val("3"), T.Val("8")); 22 T.CheckCall(T.Val("31"), T.Val("3"), T.NewObject("([1])")); 23 T.CheckCall(T.Val("3[object Object]"), T.Val("3"), T.NewObject("({})")); 24 } 25 26 27 TEST(BinopSubtract) { 28 FunctionTester T("(function(a,b) { return a - b; })"); 29 30 T.CheckCall(3, 4, 1); 31 T.CheckCall(3.0, 4.5, 1.5); 32 T.CheckCall(T.Val(-9), T.Val("0"), T.Val(9)); 33 T.CheckCall(T.Val(-9), T.Val(0.0), T.Val("9")); 34 T.CheckCall(T.Val(1), T.Val("3"), T.Val("2")); 35 T.CheckCall(T.nan(), T.Val("3"), T.Val("B")); 36 T.CheckCall(T.Val(2), T.Val("3"), T.NewObject("([1])")); 37 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})")); 38 } 39 40 41 TEST(BinopMultiply) { 42 FunctionTester T("(function(a,b) { return a * b; })"); 43 44 T.CheckCall(6, 3, 2); 45 T.CheckCall(4.5, 2.0, 2.25); 46 T.CheckCall(T.Val(6), T.Val("3"), T.Val(2)); 47 T.CheckCall(T.Val(4.5), T.Val(2.0), T.Val("2.25")); 48 T.CheckCall(T.Val(6), T.Val("3"), T.Val("2")); 49 T.CheckCall(T.nan(), T.Val("3"), T.Val("B")); 50 T.CheckCall(T.Val(3), T.Val("3"), T.NewObject("([1])")); 51 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})")); 52 } 53 54 55 TEST(BinopDivide) { 56 FunctionTester T("(function(a,b) { return a / b; })"); 57 58 T.CheckCall(2, 8, 4); 59 T.CheckCall(2.1, 8.4, 4); 60 T.CheckCall(V8_INFINITY, 8, 0); 61 T.CheckCall(-V8_INFINITY, -8, 0); 62 T.CheckCall(T.infinity(), T.Val(8), T.Val("0")); 63 T.CheckCall(T.minus_infinity(), T.Val("-8"), T.Val(0.0)); 64 T.CheckCall(T.Val(1.5), T.Val("3"), T.Val("2")); 65 T.CheckCall(T.nan(), T.Val("3"), T.Val("B")); 66 T.CheckCall(T.Val(1.5), T.Val("3"), T.NewObject("([2])")); 67 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})")); 68 } 69 70 71 TEST(BinopModulus) { 72 FunctionTester T("(function(a,b) { return a % b; })"); 73 74 T.CheckCall(3, 8, 5); 75 T.CheckCall(T.Val(3), T.Val("8"), T.Val(5)); 76 T.CheckCall(T.Val(3), T.Val(8), T.Val("5")); 77 T.CheckCall(T.Val(1), T.Val("3"), T.Val("2")); 78 T.CheckCall(T.nan(), T.Val("3"), T.Val("B")); 79 T.CheckCall(T.Val(1), T.Val("3"), T.NewObject("([2])")); 80 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})")); 81 } 82 83 84 TEST(BinopShiftLeft) { 85 FunctionTester T("(function(a,b) { return a << b; })"); 86 87 T.CheckCall(4, 2, 1); 88 T.CheckCall(T.Val(4), T.Val("2"), T.Val(1)); 89 T.CheckCall(T.Val(4), T.Val(2), T.Val("1")); 90 } 91 92 93 TEST(BinopShiftRight) { 94 FunctionTester T("(function(a,b) { return a >> b; })"); 95 96 T.CheckCall(4, 8, 1); 97 T.CheckCall(-4, -8, 1); 98 T.CheckCall(T.Val(4), T.Val("8"), T.Val(1)); 99 T.CheckCall(T.Val(4), T.Val(8), T.Val("1")); 100 } 101 102 103 TEST(BinopShiftRightLogical) { 104 FunctionTester T("(function(a,b) { return a >>> b; })"); 105 106 T.CheckCall(4, 8, 1); 107 T.CheckCall(0x7ffffffc, -8, 1); 108 T.CheckCall(T.Val(4), T.Val("8"), T.Val(1)); 109 T.CheckCall(T.Val(4), T.Val(8), T.Val("1")); 110 } 111 112 113 TEST(BinopAnd) { 114 FunctionTester T("(function(a,b) { return a & b; })"); 115 116 T.CheckCall(7, 7, 15); 117 T.CheckCall(7, 15, 7); 118 T.CheckCall(T.Val(7), T.Val("15"), T.Val(7)); 119 T.CheckCall(T.Val(7), T.Val(15), T.Val("7")); 120 } 121 122 123 TEST(BinopOr) { 124 FunctionTester T("(function(a,b) { return a | b; })"); 125 126 T.CheckCall(6, 4, 2); 127 T.CheckCall(6, 2, 4); 128 T.CheckCall(T.Val(6), T.Val("2"), T.Val(4)); 129 T.CheckCall(T.Val(6), T.Val(2), T.Val("4")); 130 } 131 132 133 TEST(BinopXor) { 134 FunctionTester T("(function(a,b) { return a ^ b; })"); 135 136 T.CheckCall(7, 15, 8); 137 T.CheckCall(7, 8, 15); 138 T.CheckCall(T.Val(7), T.Val("8"), T.Val(15)); 139 T.CheckCall(T.Val(7), T.Val(8), T.Val("15")); 140 } 141 142 143 TEST(BinopStrictEqual) { 144 FunctionTester T("(function(a,b) { return a === b; })"); 145 146 T.CheckTrue(7, 7); 147 T.CheckFalse(7, 8); 148 T.CheckTrue(7.1, 7.1); 149 T.CheckFalse(7.1, 8.1); 150 151 T.CheckTrue(T.Val("7.1"), T.Val("7.1")); 152 T.CheckFalse(T.Val(7.1), T.Val("7.1")); 153 T.CheckFalse(T.Val(7), T.undefined()); 154 T.CheckFalse(T.undefined(), T.Val(7)); 155 156 CompileRun("var o = { desc : 'I am a singleton' }"); 157 T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])")); 158 T.CheckFalse(T.NewObject("({})"), T.NewObject("({})")); 159 T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)")); 160 } 161 162 163 TEST(BinopEqual) { 164 FunctionTester T("(function(a,b) { return a == b; })"); 165 166 T.CheckTrue(7, 7); 167 T.CheckFalse(7, 8); 168 T.CheckTrue(7.1, 7.1); 169 T.CheckFalse(7.1, 8.1); 170 171 T.CheckTrue(T.Val("7.1"), T.Val("7.1")); 172 T.CheckTrue(T.Val(7.1), T.Val("7.1")); 173 174 CompileRun("var o = { desc : 'I am a singleton' }"); 175 T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])")); 176 T.CheckFalse(T.NewObject("({})"), T.NewObject("({})")); 177 T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)")); 178 } 179 180 181 TEST(BinopNotEqual) { 182 FunctionTester T("(function(a,b) { return a != b; })"); 183 184 T.CheckFalse(7, 7); 185 T.CheckTrue(7, 8); 186 T.CheckFalse(7.1, 7.1); 187 T.CheckTrue(7.1, 8.1); 188 189 T.CheckFalse(T.Val("7.1"), T.Val("7.1")); 190 T.CheckFalse(T.Val(7.1), T.Val("7.1")); 191 192 CompileRun("var o = { desc : 'I am a singleton' }"); 193 T.CheckTrue(T.NewObject("([1])"), T.NewObject("([1])")); 194 T.CheckTrue(T.NewObject("({})"), T.NewObject("({})")); 195 T.CheckFalse(T.NewObject("(o)"), T.NewObject("(o)")); 196 } 197 198 199 TEST(BinopLessThan) { 200 FunctionTester T("(function(a,b) { return a < b; })"); 201 202 T.CheckTrue(7, 8); 203 T.CheckFalse(8, 7); 204 T.CheckTrue(-8.1, -8); 205 T.CheckFalse(-8, -8.1); 206 T.CheckFalse(0.111, 0.111); 207 208 T.CheckFalse(T.Val("7.1"), T.Val("7.1")); 209 T.CheckFalse(T.Val(7.1), T.Val("6.1")); 210 T.CheckFalse(T.Val(7.1), T.Val("7.1")); 211 T.CheckTrue(T.Val(7.1), T.Val("8.1")); 212 } 213 214 215 TEST(BinopLessThanEqual) { 216 FunctionTester T("(function(a,b) { return a <= b; })"); 217 218 T.CheckTrue(7, 8); 219 T.CheckFalse(8, 7); 220 T.CheckTrue(-8.1, -8); 221 T.CheckFalse(-8, -8.1); 222 T.CheckTrue(0.111, 0.111); 223 224 T.CheckTrue(T.Val("7.1"), T.Val("7.1")); 225 T.CheckFalse(T.Val(7.1), T.Val("6.1")); 226 T.CheckTrue(T.Val(7.1), T.Val("7.1")); 227 T.CheckTrue(T.Val(7.1), T.Val("8.1")); 228 } 229 230 231 TEST(BinopGreaterThan) { 232 FunctionTester T("(function(a,b) { return a > b; })"); 233 234 T.CheckFalse(7, 8); 235 T.CheckTrue(8, 7); 236 T.CheckFalse(-8.1, -8); 237 T.CheckTrue(-8, -8.1); 238 T.CheckFalse(0.111, 0.111); 239 240 T.CheckFalse(T.Val("7.1"), T.Val("7.1")); 241 T.CheckTrue(T.Val(7.1), T.Val("6.1")); 242 T.CheckFalse(T.Val(7.1), T.Val("7.1")); 243 T.CheckFalse(T.Val(7.1), T.Val("8.1")); 244 } 245 246 247 TEST(BinopGreaterThanOrEqual) { 248 FunctionTester T("(function(a,b) { return a >= b; })"); 249 250 T.CheckFalse(7, 8); 251 T.CheckTrue(8, 7); 252 T.CheckFalse(-8.1, -8); 253 T.CheckTrue(-8, -8.1); 254 T.CheckTrue(0.111, 0.111); 255 256 T.CheckTrue(T.Val("7.1"), T.Val("7.1")); 257 T.CheckTrue(T.Val(7.1), T.Val("6.1")); 258 T.CheckTrue(T.Val(7.1), T.Val("7.1")); 259 T.CheckFalse(T.Val(7.1), T.Val("8.1")); 260 } 261 262 263 TEST(BinopIn) { 264 FunctionTester T("(function(a,b) { return a in b; })"); 265 266 T.CheckTrue(T.Val("x"), T.NewObject("({x:23})")); 267 T.CheckFalse(T.Val("y"), T.NewObject("({x:42})")); 268 T.CheckFalse(T.Val(123), T.NewObject("({x:65})")); 269 T.CheckTrue(T.Val(1), T.NewObject("([1,2,3])")); 270 } 271 272 273 TEST(BinopInstanceOf) { 274 FunctionTester T("(function(a,b) { return a instanceof b; })"); 275 276 T.CheckTrue(T.NewObject("(new Number(23))"), T.NewObject("Number")); 277 T.CheckFalse(T.NewObject("(new Number(23))"), T.NewObject("String")); 278 T.CheckFalse(T.NewObject("(new String('a'))"), T.NewObject("Number")); 279 T.CheckTrue(T.NewObject("(new String('b'))"), T.NewObject("String")); 280 T.CheckFalse(T.Val(1), T.NewObject("Number")); 281 T.CheckFalse(T.Val("abc"), T.NewObject("String")); 282 283 CompileRun("var bound = (function() {}).bind(undefined)"); 284 T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("bound")); 285 T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("Object")); 286 T.CheckFalse(T.NewObject("(new bound())"), T.NewObject("Number")); 287 } 288 289 290 TEST(UnopNot) { 291 FunctionTester T("(function(a) { return !a; })"); 292 293 T.CheckCall(T.true_value(), T.false_value(), T.undefined()); 294 T.CheckCall(T.false_value(), T.true_value(), T.undefined()); 295 T.CheckCall(T.true_value(), T.Val(0.0), T.undefined()); 296 T.CheckCall(T.false_value(), T.Val(123), T.undefined()); 297 T.CheckCall(T.false_value(), T.Val("x"), T.undefined()); 298 T.CheckCall(T.true_value(), T.undefined(), T.undefined()); 299 T.CheckCall(T.true_value(), T.nan(), T.undefined()); 300 } 301 302 303 TEST(UnopCountPost) { 304 FunctionTester T("(function(a) { return a++; })"); 305 306 T.CheckCall(T.Val(0.0), T.Val(0.0), T.undefined()); 307 T.CheckCall(T.Val(2.3), T.Val(2.3), T.undefined()); 308 T.CheckCall(T.Val(123), T.Val(123), T.undefined()); 309 T.CheckCall(T.Val(7), T.Val("7"), T.undefined()); 310 T.CheckCall(T.nan(), T.Val("x"), T.undefined()); 311 T.CheckCall(T.nan(), T.undefined(), T.undefined()); 312 T.CheckCall(T.Val(1.0), T.true_value(), T.undefined()); 313 T.CheckCall(T.Val(0.0), T.false_value(), T.undefined()); 314 T.CheckCall(T.nan(), T.nan(), T.undefined()); 315 } 316 317 318 TEST(UnopCountPre) { 319 FunctionTester T("(function(a) { return ++a; })"); 320 321 T.CheckCall(T.Val(1.0), T.Val(0.0), T.undefined()); 322 T.CheckCall(T.Val(3.3), T.Val(2.3), T.undefined()); 323 T.CheckCall(T.Val(124), T.Val(123), T.undefined()); 324 T.CheckCall(T.Val(8), T.Val("7"), T.undefined()); 325 T.CheckCall(T.nan(), T.Val("x"), T.undefined()); 326 T.CheckCall(T.nan(), T.undefined(), T.undefined()); 327 T.CheckCall(T.Val(2.0), T.true_value(), T.undefined()); 328 T.CheckCall(T.Val(1.0), T.false_value(), T.undefined()); 329 T.CheckCall(T.nan(), T.nan(), T.undefined()); 330 } 331 332 333 TEST(PropertyNamedLoad) { 334 FunctionTester T("(function(a,b) { return a.x; })"); 335 336 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined()); 337 T.CheckCall(T.undefined(), T.NewObject("({y:23})"), T.undefined()); 338 } 339 340 341 TEST(PropertyKeyedLoad) { 342 FunctionTester T("(function(a,b) { return a[b]; })"); 343 344 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.Val("x")); 345 T.CheckCall(T.Val(42), T.NewObject("([23,42,65])"), T.Val(1)); 346 T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val("y")); 347 T.CheckCall(T.undefined(), T.NewObject("([23,42,65])"), T.Val(4)); 348 } 349 350 351 TEST(PropertyNamedStore) { 352 FunctionTester T("(function(a) { a.x = 7; return a.x; })"); 353 354 T.CheckCall(T.Val(7), T.NewObject("({})"), T.undefined()); 355 T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.undefined()); 356 } 357 358 359 TEST(PropertyKeyedStore) { 360 FunctionTester T("(function(a,b) { a[b] = 7; return a.x; })"); 361 362 T.CheckCall(T.Val(7), T.NewObject("({})"), T.Val("x")); 363 T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.Val("x")); 364 T.CheckCall(T.Val(9), T.NewObject("({x:9})"), T.Val("y")); 365 } 366 367 368 TEST(PropertyNamedDelete) { 369 FunctionTester T("(function(a) { return delete a.x; })"); 370 371 CompileRun("var o = Object.create({}, { x: { value:23 } });"); 372 T.CheckTrue(T.NewObject("({x:42})"), T.undefined()); 373 T.CheckTrue(T.NewObject("({})"), T.undefined()); 374 T.CheckFalse(T.NewObject("(o)"), T.undefined()); 375 } 376 377 378 TEST(PropertyKeyedDelete) { 379 FunctionTester T("(function(a, b) { return delete a[b]; })"); 380 381 CompileRun("function getX() { return 'x'; }"); 382 CompileRun("var o = Object.create({}, { x: { value:23 } });"); 383 T.CheckTrue(T.NewObject("({x:42})"), T.Val("x")); 384 T.CheckFalse(T.NewObject("(o)"), T.Val("x")); 385 T.CheckFalse(T.NewObject("(o)"), T.NewObject("({toString:getX})")); 386 } 387 388 389 TEST(GlobalLoad) { 390 FunctionTester T("(function() { return g; })"); 391 392 T.CheckThrows(T.undefined(), T.undefined()); 393 CompileRun("var g = 23;"); 394 T.CheckCall(T.Val(23)); 395 } 396 397 398 TEST(GlobalStoreSloppy) { 399 FunctionTester T("(function(a,b) { g = a + b; return g; })"); 400 401 T.CheckCall(T.Val(33), T.Val(22), T.Val(11)); 402 CompileRun("delete g"); 403 CompileRun("const g = 23"); 404 T.CheckCall(T.Val(23), T.Val(55), T.Val(44)); 405 } 406 407 408 TEST(GlobalStoreStrict) { 409 FunctionTester T("(function(a,b) { 'use strict'; g = a + b; return g; })"); 410 411 T.CheckThrows(T.Val(22), T.Val(11)); 412 CompileRun("var g = 'a global variable';"); 413 T.CheckCall(T.Val(33), T.Val(22), T.Val(11)); 414 } 415 416 417 TEST(ContextLoad) { 418 FunctionTester T("(function(a,b) { (function(){a}); return a + b; })"); 419 420 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 421 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 422 } 423 424 425 TEST(ContextStore) { 426 FunctionTester T("(function(a,b) { (function(){x}); var x = a; return x; })"); 427 428 T.CheckCall(T.Val(23), T.Val(23), T.undefined()); 429 T.CheckCall(T.Val("a"), T.Val("a"), T.undefined()); 430 } 431 432 433 TEST(LookupLoad) { 434 FunctionTester T("(function(a,b) { with(a) { return x + b; } })"); 435 436 T.CheckCall(T.Val(24), T.NewObject("({x:23})"), T.Val(1)); 437 T.CheckCall(T.Val(32), T.NewObject("({x:23, b:9})"), T.Val(2)); 438 T.CheckCall(T.Val(45), T.NewObject("({__proto__:{x:42}})"), T.Val(3)); 439 T.CheckCall(T.Val(69), T.NewObject("({get x() { return 65; }})"), T.Val(4)); 440 } 441 442 443 TEST(LookupStore) { 444 FunctionTester T("(function(a,b) { var x; with(a) { x = b; } return x; })"); 445 446 T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val(1)); 447 T.CheckCall(T.Val(2), T.NewObject("({y:23})"), T.Val(2)); 448 T.CheckCall(T.Val(23), T.NewObject("({b:23})"), T.Val(3)); 449 T.CheckCall(T.undefined(), T.NewObject("({__proto__:{x:42}})"), T.Val(4)); 450 } 451 452 453 TEST(BlockLoadStore) { 454 FLAG_harmony_scoping = true; 455 FunctionTester T("(function(a) { 'use strict'; { let x = a+a; return x; }})"); 456 457 T.CheckCall(T.Val(46), T.Val(23)); 458 T.CheckCall(T.Val("aa"), T.Val("a")); 459 } 460 461 462 TEST(BlockLoadStoreNested) { 463 FLAG_harmony_scoping = true; 464 const char* src = 465 "(function(a,b) {" 466 "'use strict';" 467 "{ let x = a, y = a;" 468 " { let y = b;" 469 " return x + y;" 470 " }" 471 "}})"; 472 FunctionTester T(src); 473 474 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 475 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 476 } 477 478 479 TEST(ObjectLiteralComputed) { 480 FunctionTester T("(function(a,b) { o = { x:a+b }; return o.x; })"); 481 482 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 483 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 484 } 485 486 487 TEST(ObjectLiteralNonString) { 488 FunctionTester T("(function(a,b) { o = { 7:a+b }; return o[7]; })"); 489 490 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 491 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 492 } 493 494 495 TEST(ObjectLiteralPrototype) { 496 FunctionTester T("(function(a) { o = { __proto__:a }; return o.x; })"); 497 498 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined()); 499 T.CheckCall(T.undefined(), T.NewObject("({y:42})"), T.undefined()); 500 } 501 502 503 TEST(ObjectLiteralGetter) { 504 FunctionTester T("(function(a) { o = { get x() {return a} }; return o.x; })"); 505 506 T.CheckCall(T.Val(23), T.Val(23), T.undefined()); 507 T.CheckCall(T.Val("x"), T.Val("x"), T.undefined()); 508 } 509 510 511 TEST(ArrayLiteral) { 512 FunctionTester T("(function(a,b) { o = [1, a + b, 3]; return o[1]; })"); 513 514 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 515 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 516 } 517 518 519 TEST(RegExpLiteral) { 520 FunctionTester T("(function(a) { o = /b/; return o.test(a); })"); 521 522 T.CheckTrue(T.Val("abc")); 523 T.CheckFalse(T.Val("xyz")); 524 } 525