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(GlobalStoreStrict) { 398 FunctionTester T("(function(a,b) { 'use strict'; g = a + b; return g; })"); 399 400 T.CheckThrows(T.Val(22), T.Val(11)); 401 CompileRun("var g = 'a global variable';"); 402 T.CheckCall(T.Val(33), T.Val(22), T.Val(11)); 403 } 404 405 406 TEST(ContextLoad) { 407 FunctionTester T("(function(a,b) { (function(){a}); return a + b; })"); 408 409 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 410 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 411 } 412 413 414 TEST(ContextStore) { 415 FunctionTester T("(function(a,b) { (function(){x}); var x = a; return x; })"); 416 417 T.CheckCall(T.Val(23), T.Val(23), T.undefined()); 418 T.CheckCall(T.Val("a"), T.Val("a"), T.undefined()); 419 } 420 421 422 TEST(LookupLoad) { 423 FunctionTester T("(function(a,b) { with(a) { return x + b; } })"); 424 425 T.CheckCall(T.Val(24), T.NewObject("({x:23})"), T.Val(1)); 426 T.CheckCall(T.Val(32), T.NewObject("({x:23, b:9})"), T.Val(2)); 427 T.CheckCall(T.Val(45), T.NewObject("({__proto__:{x:42}})"), T.Val(3)); 428 T.CheckCall(T.Val(69), T.NewObject("({get x() { return 65; }})"), T.Val(4)); 429 } 430 431 432 TEST(LookupStore) { 433 FunctionTester T("(function(a,b) { var x; with(a) { x = b; } return x; })"); 434 435 T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val(1)); 436 T.CheckCall(T.Val(2), T.NewObject("({y:23})"), T.Val(2)); 437 T.CheckCall(T.Val(23), T.NewObject("({b:23})"), T.Val(3)); 438 T.CheckCall(T.undefined(), T.NewObject("({__proto__:{x:42}})"), T.Val(4)); 439 } 440 441 442 TEST(BlockLoadStore) { 443 FunctionTester T("(function(a) { 'use strict'; { let x = a+a; return x; }})"); 444 445 T.CheckCall(T.Val(46), T.Val(23)); 446 T.CheckCall(T.Val("aa"), T.Val("a")); 447 } 448 449 450 TEST(BlockLoadStoreNested) { 451 const char* src = 452 "(function(a,b) {" 453 "'use strict';" 454 "{ let x = a, y = a;" 455 " { let y = b;" 456 " return x + y;" 457 " }" 458 "}})"; 459 FunctionTester T(src); 460 461 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 462 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 463 } 464 465 466 TEST(ObjectLiteralComputed) { 467 FunctionTester T("(function(a,b) { o = { x:a+b }; return o.x; })"); 468 469 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 470 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 471 } 472 473 474 TEST(ObjectLiteralNonString) { 475 FunctionTester T("(function(a,b) { o = { 7:a+b }; return o[7]; })"); 476 477 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 478 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 479 } 480 481 482 TEST(ObjectLiteralPrototype) { 483 FunctionTester T("(function(a) { o = { __proto__:a }; return o.x; })"); 484 485 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined()); 486 T.CheckCall(T.undefined(), T.NewObject("({y:42})"), T.undefined()); 487 } 488 489 490 TEST(ObjectLiteralGetter) { 491 FunctionTester T("(function(a) { o = { get x() {return a} }; return o.x; })"); 492 493 T.CheckCall(T.Val(23), T.Val(23), T.undefined()); 494 T.CheckCall(T.Val("x"), T.Val("x"), T.undefined()); 495 } 496 497 498 TEST(ArrayLiteral) { 499 FunctionTester T("(function(a,b) { o = [1, a + b, 3]; return o[1]; })"); 500 501 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 502 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 503 } 504 505 506 TEST(RegExpLiteral) { 507 FunctionTester T("(function(a) { o = /b/; return o.test(a); })"); 508 509 T.CheckTrue(T.Val("abc")); 510 T.CheckFalse(T.Val("xyz")); 511 } 512 513 514 TEST(ClassLiteral) { 515 const char* src = 516 "(function(a,b) {" 517 " class C {" 518 " x() { return a; }" 519 " static y() { return b; }" 520 " get z() { return 0; }" 521 " constructor() {}" 522 " }" 523 " return new C().x() + C.y();" 524 "})"; 525 FunctionTester T(src); 526 527 T.CheckCall(T.Val(65), T.Val(23), T.Val(42)); 528 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b")); 529 } 530 531 } // namespace compiler 532 } // namespace internal 533 } // namespace v8 534