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