| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 Object.observe(obj3, observer.callback); | 296 Object.observe(obj3, observer.callback); |
| 297 Object.deliverChangeRecords(observer.callback); | 297 Object.deliverChangeRecords(observer.callback); |
| 298 observer.assertCallbackRecords([ | 298 observer.assertCallbackRecords([ |
| 299 { object: obj, type: 'foo1' }, | 299 { object: obj, type: 'foo1' }, |
| 300 { object: obj2, type: 'foo2' }, | 300 { object: obj2, type: 'foo2' }, |
| 301 { object: obj3, type: 'foo3' } | 301 { object: obj3, type: 'foo3' } |
| 302 ]); | 302 ]); |
| 303 | 303 |
| 304 | 304 |
| 305 // Recursive observation. | 305 // Recursive observation. |
| 306 /* TODO(rossberg): temporarily disabled until fixed. | |
| 307 var obj = {a: 1}; | 306 var obj = {a: 1}; |
| 308 var callbackCount = 0; | 307 var callbackCount = 0; |
| 309 function recursiveObserver(r) { | 308 function recursiveObserver(r) { |
| 310 assertEquals(1, r.length); | 309 assertEquals(1, r.length); |
| 311 ++callbackCount; | 310 ++callbackCount; |
| 312 if (r[0].oldValue < 100) ++obj[r[0].name]; | 311 if (r[0].oldValue < 100) ++obj[r[0].name]; |
| 313 } | 312 } |
| 314 Object.observe(obj, recursiveObserver); | 313 Object.observe(obj, recursiveObserver); |
| 315 ++obj.a; | 314 ++obj.a; |
| 316 Object.deliverChangeRecords(recursiveObserver); | 315 Object.deliverChangeRecords(recursiveObserver); |
| 317 assertEquals(100, callbackCount); | 316 assertEquals(100, callbackCount); |
| 318 | 317 |
| 319 var obj1 = {a: 1}; | 318 var obj1 = {a: 1}; |
| 320 var obj2 = {a: 1}; | 319 var obj2 = {a: 1}; |
| 321 var recordCount = 0; | 320 var recordCount = 0; |
| 322 function recursiveObserver2(r) { | 321 function recursiveObserver2(r) { |
| 323 recordCount += r.length; | 322 recordCount += r.length; |
| 324 if (r[0].oldValue < 100) { | 323 if (r[0].oldValue < 100) { |
| 325 ++obj1.a; | 324 ++obj1.a; |
| 326 ++obj2.a; | 325 ++obj2.a; |
| 327 } | 326 } |
| 328 } | 327 } |
| 329 Object.observe(obj1, recursiveObserver2); | 328 Object.observe(obj1, recursiveObserver2); |
| 330 Object.observe(obj2, recursiveObserver2); | 329 Object.observe(obj2, recursiveObserver2); |
| 331 ++obj1.a; | 330 ++obj1.a; |
| 332 Object.deliverChangeRecords(recursiveObserver2); | 331 Object.deliverChangeRecords(recursiveObserver2); |
| 333 assertEquals(199, recordCount); | 332 assertEquals(199, recordCount); |
| 334 */ | |
| 335 | 333 |
| 336 | 334 |
| 337 // Observing named properties. | 335 // Observing named properties. |
| 338 reset(); | 336 reset(); |
| 339 var obj = {a: 1} | 337 var obj = {a: 1} |
| 340 Object.observe(obj, observer.callback); | 338 Object.observe(obj, observer.callback); |
| 341 obj.a = 2; | 339 obj.a = 2; |
| 342 obj["a"] = 3; | 340 obj["a"] = 3; |
| 343 delete obj.a; | 341 delete obj.a; |
| 344 obj.a = 4; | 342 obj.a = 4; |
| 345 obj.a = 4; // ignored | 343 obj.a = 4; // ignored |
| 346 obj.a = 5; | 344 obj.a = 5; |
| 347 Object.defineProperty(obj, "a", {value: 6}); | 345 Object.defineProperty(obj, "a", {value: 6}); |
| 348 Object.defineProperty(obj, "a", {writable: false}); | 346 Object.defineProperty(obj, "a", {writable: false}); |
| 349 obj.a = 7; // ignored | 347 obj.a = 7; // ignored |
| 350 Object.defineProperty(obj, "a", {value: 8}); | 348 Object.defineProperty(obj, "a", {value: 8}); |
| 351 Object.defineProperty(obj, "a", {value: 7, writable: true}); | 349 Object.defineProperty(obj, "a", {value: 7, writable: true}); |
| 352 Object.defineProperty(obj, "a", {get: function() {}}); | 350 Object.defineProperty(obj, "a", {get: function() {}}); |
| 353 Object.defineProperty(obj, "a", {get: frozenFunction}); | 351 Object.defineProperty(obj, "a", {get: frozenFunction}); |
| 354 Object.defineProperty(obj, "a", {get: frozenFunction}); // ignored | 352 Object.defineProperty(obj, "a", {get: frozenFunction}); // ignored |
| 355 Object.defineProperty(obj, "a", {get: frozenFunction, set: frozenFunction}); | 353 Object.defineProperty(obj, "a", {get: frozenFunction, set: frozenFunction}); |
| 356 Object.defineProperty(obj, "a", {set: frozenFunction}); // ignored | 354 Object.defineProperty(obj, "a", {set: frozenFunction}); // ignored |
| 357 Object.defineProperty(obj, "a", {get: undefined, set: frozenFunction}); | 355 Object.defineProperty(obj, "a", {get: undefined, set: frozenFunction}); |
| 358 delete obj.a; | 356 delete obj.a; |
| 359 delete obj.a; | 357 delete obj.a; |
| 360 Object.defineProperty(obj, "a", {get: function() {}, configurable: true}); | 358 Object.defineProperty(obj, "a", {get: function() {}, configurable: true}); |
| 361 Object.defineProperty(obj, "a", {value: 9, writable: true}); | 359 Object.defineProperty(obj, "a", {value: 9, writable: true}); |
| 362 obj.a = 10; | 360 obj.a = 10; |
| 361 ++obj.a; |
| 362 obj.a++; |
| 363 obj.a *= 3; |
| 363 delete obj.a; | 364 delete obj.a; |
| 364 Object.defineProperty(obj, "a", {value: 11, configurable: true}); | 365 Object.defineProperty(obj, "a", {value: 11, configurable: true}); |
| 365 Object.deliverChangeRecords(observer.callback); | 366 Object.deliverChangeRecords(observer.callback); |
| 366 observer.assertCallbackRecords([ | 367 observer.assertCallbackRecords([ |
| 367 { object: obj, name: "a", type: "updated", oldValue: 1 }, | 368 { object: obj, name: "a", type: "updated", oldValue: 1 }, |
| 368 { object: obj, name: "a", type: "updated", oldValue: 2 }, | 369 { object: obj, name: "a", type: "updated", oldValue: 2 }, |
| 369 { object: obj, name: "a", type: "deleted", oldValue: 3 }, | 370 { object: obj, name: "a", type: "deleted", oldValue: 3 }, |
| 370 { object: obj, name: "a", type: "new" }, | 371 { object: obj, name: "a", type: "new" }, |
| 371 { object: obj, name: "a", type: "updated", oldValue: 4 }, | 372 { object: obj, name: "a", type: "updated", oldValue: 4 }, |
| 372 { object: obj, name: "a", type: "updated", oldValue: 5 }, | 373 { object: obj, name: "a", type: "updated", oldValue: 5 }, |
| 373 { object: obj, name: "a", type: "reconfigured", oldValue: 6 }, | 374 { object: obj, name: "a", type: "reconfigured", oldValue: 6 }, |
| 374 { object: obj, name: "a", type: "updated", oldValue: 6 }, | 375 { object: obj, name: "a", type: "updated", oldValue: 6 }, |
| 375 { object: obj, name: "a", type: "reconfigured", oldValue: 8 }, | 376 { object: obj, name: "a", type: "reconfigured", oldValue: 8 }, |
| 376 { object: obj, name: "a", type: "reconfigured", oldValue: 7 }, | 377 { object: obj, name: "a", type: "reconfigured", oldValue: 7 }, |
| 377 { object: obj, name: "a", type: "reconfigured" }, | 378 { object: obj, name: "a", type: "reconfigured" }, |
| 378 { object: obj, name: "a", type: "reconfigured" }, | 379 { object: obj, name: "a", type: "reconfigured" }, |
| 379 { object: obj, name: "a", type: "reconfigured" }, | 380 { object: obj, name: "a", type: "reconfigured" }, |
| 380 { object: obj, name: "a", type: "deleted" }, | 381 { object: obj, name: "a", type: "deleted" }, |
| 381 { object: obj, name: "a", type: "new" }, | 382 { object: obj, name: "a", type: "new" }, |
| 382 { object: obj, name: "a", type: "reconfigured" }, | 383 { object: obj, name: "a", type: "reconfigured" }, |
| 383 { object: obj, name: "a", type: "updated", oldValue: 9 }, | 384 { object: obj, name: "a", type: "updated", oldValue: 9 }, |
| 384 { object: obj, name: "a", type: "deleted", oldValue: 10 }, | 385 { object: obj, name: "a", type: "updated", oldValue: 10 }, |
| 386 { object: obj, name: "a", type: "updated", oldValue: 11 }, |
| 387 { object: obj, name: "a", type: "updated", oldValue: 12 }, |
| 388 { object: obj, name: "a", type: "deleted", oldValue: 36 }, |
| 385 { object: obj, name: "a", type: "new" }, | 389 { object: obj, name: "a", type: "new" }, |
| 386 ]); | 390 ]); |
| 387 | 391 |
| 388 | 392 |
| 389 // Observing indexed properties. | 393 // Observing indexed properties. |
| 390 reset(); | 394 reset(); |
| 391 var obj = {'1': 1} | 395 var obj = {'1': 1} |
| 392 Object.observe(obj, observer.callback); | 396 Object.observe(obj, observer.callback); |
| 393 obj[1] = 2; | 397 obj[1] = 2; |
| 394 obj[1] = 3; | 398 obj[1] = 3; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 405 Object.defineProperty(obj, "1", {get: frozenFunction}); | 409 Object.defineProperty(obj, "1", {get: frozenFunction}); |
| 406 Object.defineProperty(obj, "1", {get: frozenFunction}); // ignored | 410 Object.defineProperty(obj, "1", {get: frozenFunction}); // ignored |
| 407 Object.defineProperty(obj, "1", {get: frozenFunction, set: frozenFunction}); | 411 Object.defineProperty(obj, "1", {get: frozenFunction, set: frozenFunction}); |
| 408 Object.defineProperty(obj, "1", {set: frozenFunction}); // ignored | 412 Object.defineProperty(obj, "1", {set: frozenFunction}); // ignored |
| 409 Object.defineProperty(obj, "1", {get: undefined, set: frozenFunction}); | 413 Object.defineProperty(obj, "1", {get: undefined, set: frozenFunction}); |
| 410 delete obj[1]; | 414 delete obj[1]; |
| 411 delete obj[1]; | 415 delete obj[1]; |
| 412 Object.defineProperty(obj, "1", {get: function() {}, configurable: true}); | 416 Object.defineProperty(obj, "1", {get: function() {}, configurable: true}); |
| 413 Object.defineProperty(obj, "1", {value: 9, writable: true}); | 417 Object.defineProperty(obj, "1", {value: 9, writable: true}); |
| 414 obj[1] = 10; | 418 obj[1] = 10; |
| 419 ++obj[1]; |
| 420 obj[1]++; |
| 421 obj[1] *= 3; |
| 415 delete obj[1]; | 422 delete obj[1]; |
| 416 Object.defineProperty(obj, "1", {value: 11, configurable: true}); | 423 Object.defineProperty(obj, "1", {value: 11, configurable: true}); |
| 417 Object.deliverChangeRecords(observer.callback); | 424 Object.deliverChangeRecords(observer.callback); |
| 418 observer.assertCallbackRecords([ | 425 observer.assertCallbackRecords([ |
| 419 { object: obj, name: "1", type: "updated", oldValue: 1 }, | 426 { object: obj, name: "1", type: "updated", oldValue: 1 }, |
| 420 { object: obj, name: "1", type: "updated", oldValue: 2 }, | 427 { object: obj, name: "1", type: "updated", oldValue: 2 }, |
| 421 { object: obj, name: "1", type: "deleted", oldValue: 3 }, | 428 { object: obj, name: "1", type: "deleted", oldValue: 3 }, |
| 422 { object: obj, name: "1", type: "new" }, | 429 { object: obj, name: "1", type: "new" }, |
| 423 { object: obj, name: "1", type: "updated", oldValue: 4 }, | 430 { object: obj, name: "1", type: "updated", oldValue: 4 }, |
| 424 { object: obj, name: "1", type: "updated", oldValue: 5 }, | 431 { object: obj, name: "1", type: "updated", oldValue: 5 }, |
| 425 { object: obj, name: "1", type: "reconfigured", oldValue: 6 }, | 432 { object: obj, name: "1", type: "reconfigured", oldValue: 6 }, |
| 426 { object: obj, name: "1", type: "updated", oldValue: 6 }, | 433 { object: obj, name: "1", type: "updated", oldValue: 6 }, |
| 427 { object: obj, name: "1", type: "reconfigured", oldValue: 8 }, | 434 { object: obj, name: "1", type: "reconfigured", oldValue: 8 }, |
| 428 { object: obj, name: "1", type: "reconfigured", oldValue: 7 }, | 435 { object: obj, name: "1", type: "reconfigured", oldValue: 7 }, |
| 429 { object: obj, name: "1", type: "reconfigured" }, | 436 { object: obj, name: "1", type: "reconfigured" }, |
| 430 { object: obj, name: "1", type: "reconfigured" }, | 437 { object: obj, name: "1", type: "reconfigured" }, |
| 431 { object: obj, name: "1", type: "reconfigured" }, | 438 { object: obj, name: "1", type: "reconfigured" }, |
| 432 { object: obj, name: "1", type: "deleted" }, | 439 { object: obj, name: "1", type: "deleted" }, |
| 433 { object: obj, name: "1", type: "new" }, | 440 { object: obj, name: "1", type: "new" }, |
| 434 { object: obj, name: "1", type: "reconfigured" }, | 441 { object: obj, name: "1", type: "reconfigured" }, |
| 435 { object: obj, name: "1", type: "updated", oldValue: 9 }, | 442 { object: obj, name: "1", type: "updated", oldValue: 9 }, |
| 436 { object: obj, name: "1", type: "deleted", oldValue: 10 }, | 443 { object: obj, name: "1", type: "updated", oldValue: 10 }, |
| 444 { object: obj, name: "1", type: "updated", oldValue: 11 }, |
| 445 { object: obj, name: "1", type: "updated", oldValue: 12 }, |
| 446 { object: obj, name: "1", type: "deleted", oldValue: 36 }, |
| 437 { object: obj, name: "1", type: "new" }, | 447 { object: obj, name: "1", type: "new" }, |
| 438 ]); | 448 ]); |
| 439 | 449 |
| 440 | 450 |
| 441 // Test all kinds of objects generically. | 451 // Test all kinds of objects generically. |
| 442 function TestObserveConfigurable(obj, prop) { | 452 function TestObserveConfigurable(obj, prop) { |
| 443 reset(); | 453 reset(); |
| 444 obj[prop] = 1; | 454 obj[prop] = 1; |
| 445 Object.observe(obj, observer.callback); | 455 Object.observe(obj, observer.callback); |
| 446 obj[prop] = 2; | 456 obj[prop] = 2; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 463 obj.__defineSetter__(prop, frozenFunction); // ignored | 473 obj.__defineSetter__(prop, frozenFunction); // ignored |
| 464 obj.__defineSetter__(prop, function() {}); | 474 obj.__defineSetter__(prop, function() {}); |
| 465 obj.__defineGetter__(prop, function() {}); | 475 obj.__defineGetter__(prop, function() {}); |
| 466 delete obj[prop]; | 476 delete obj[prop]; |
| 467 delete obj[prop]; // ignored | 477 delete obj[prop]; // ignored |
| 468 obj.__defineGetter__(prop, function() {}); | 478 obj.__defineGetter__(prop, function() {}); |
| 469 delete obj[prop]; | 479 delete obj[prop]; |
| 470 Object.defineProperty(obj, prop, {get: function() {}, configurable: true}); | 480 Object.defineProperty(obj, prop, {get: function() {}, configurable: true}); |
| 471 Object.defineProperty(obj, prop, {value: 9, writable: true}); | 481 Object.defineProperty(obj, prop, {value: 9, writable: true}); |
| 472 obj[prop] = 10; | 482 obj[prop] = 10; |
| 483 ++obj[prop]; |
| 484 obj[prop]++; |
| 485 obj[prop] *= 3; |
| 473 delete obj[prop]; | 486 delete obj[prop]; |
| 474 Object.defineProperty(obj, prop, {value: 11, configurable: true}); | 487 Object.defineProperty(obj, prop, {value: 11, configurable: true}); |
| 475 Object.deliverChangeRecords(observer.callback); | 488 Object.deliverChangeRecords(observer.callback); |
| 476 observer.assertCallbackRecords([ | 489 observer.assertCallbackRecords([ |
| 477 { object: obj, name: prop, type: "updated", oldValue: 1 }, | 490 { object: obj, name: prop, type: "updated", oldValue: 1 }, |
| 478 { object: obj, name: prop, type: "updated", oldValue: 2 }, | 491 { object: obj, name: prop, type: "updated", oldValue: 2 }, |
| 479 { object: obj, name: prop, type: "deleted", oldValue: 3 }, | 492 { object: obj, name: prop, type: "deleted", oldValue: 3 }, |
| 480 { object: obj, name: prop, type: "new" }, | 493 { object: obj, name: prop, type: "new" }, |
| 481 { object: obj, name: prop, type: "updated", oldValue: 4 }, | 494 { object: obj, name: prop, type: "updated", oldValue: 4 }, |
| 482 { object: obj, name: prop, type: "updated", oldValue: 5 }, | 495 { object: obj, name: prop, type: "updated", oldValue: 5 }, |
| 483 { object: obj, name: prop, type: "reconfigured", oldValue: 6 }, | 496 { object: obj, name: prop, type: "reconfigured", oldValue: 6 }, |
| 484 { object: obj, name: prop, type: "updated", oldValue: 6 }, | 497 { object: obj, name: prop, type: "updated", oldValue: 6 }, |
| 485 { object: obj, name: prop, type: "reconfigured", oldValue: 8 }, | 498 { object: obj, name: prop, type: "reconfigured", oldValue: 8 }, |
| 486 { object: obj, name: prop, type: "reconfigured", oldValue: 7 }, | 499 { object: obj, name: prop, type: "reconfigured", oldValue: 7 }, |
| 487 { object: obj, name: prop, type: "reconfigured" }, | 500 { object: obj, name: prop, type: "reconfigured" }, |
| 488 { object: obj, name: prop, type: "reconfigured" }, | 501 { object: obj, name: prop, type: "reconfigured" }, |
| 489 { object: obj, name: prop, type: "reconfigured" }, | 502 { object: obj, name: prop, type: "reconfigured" }, |
| 490 { object: obj, name: prop, type: "reconfigured" }, | 503 { object: obj, name: prop, type: "reconfigured" }, |
| 491 { object: obj, name: prop, type: "reconfigured" }, | 504 { object: obj, name: prop, type: "reconfigured" }, |
| 492 { object: obj, name: prop, type: "deleted" }, | 505 { object: obj, name: prop, type: "deleted" }, |
| 493 { object: obj, name: prop, type: "new" }, | 506 { object: obj, name: prop, type: "new" }, |
| 494 { object: obj, name: prop, type: "deleted" }, | 507 { object: obj, name: prop, type: "deleted" }, |
| 495 { object: obj, name: prop, type: "new" }, | 508 { object: obj, name: prop, type: "new" }, |
| 496 { object: obj, name: prop, type: "reconfigured" }, | 509 { object: obj, name: prop, type: "reconfigured" }, |
| 497 { object: obj, name: prop, type: "updated", oldValue: 9 }, | 510 { object: obj, name: prop, type: "updated", oldValue: 9 }, |
| 498 { object: obj, name: prop, type: "deleted", oldValue: 10 }, | 511 { object: obj, name: prop, type: "updated", oldValue: 10 }, |
| 512 { object: obj, name: prop, type: "updated", oldValue: 11 }, |
| 513 { object: obj, name: prop, type: "updated", oldValue: 12 }, |
| 514 { object: obj, name: prop, type: "deleted", oldValue: 36 }, |
| 499 { object: obj, name: prop, type: "new" }, | 515 { object: obj, name: prop, type: "new" }, |
| 500 ]); | 516 ]); |
| 501 Object.unobserve(obj, observer.callback); | 517 Object.unobserve(obj, observer.callback); |
| 502 delete obj[prop]; | 518 delete obj[prop]; |
| 503 } | 519 } |
| 504 | 520 |
| 505 function TestObserveNonConfigurable(obj, prop, desc) { | 521 function TestObserveNonConfigurable(obj, prop, desc) { |
| 506 reset(); | 522 reset(); |
| 507 obj[prop] = 1; | 523 obj[prop] = 1; |
| 508 Object.observe(obj, observer.callback); | 524 Object.observe(obj, observer.callback); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 Object.observe(arr2, observer.callback); | 637 Object.observe(arr2, observer.callback); |
| 622 Object.observe(arr3, observer.callback); | 638 Object.observe(arr3, observer.callback); |
| 623 arr.length = 2; | 639 arr.length = 2; |
| 624 arr.length = 0; | 640 arr.length = 0; |
| 625 arr.length = 10; | 641 arr.length = 10; |
| 626 Object.defineProperty(arr, 'length', {writable: false}); | 642 Object.defineProperty(arr, 'length', {writable: false}); |
| 627 arr2.length = 0; | 643 arr2.length = 0; |
| 628 arr2.length = 1; // no change expected | 644 arr2.length = 1; // no change expected |
| 629 Object.defineProperty(arr2, 'length', {value: 1, writable: false}); | 645 Object.defineProperty(arr2, 'length', {value: 1, writable: false}); |
| 630 arr3.length = 0; | 646 arr3.length = 0; |
| 647 ++arr3.length; |
| 648 arr3.length++; |
| 649 arr3.length /= 2; |
| 631 Object.defineProperty(arr3, 'length', {value: 5}); | 650 Object.defineProperty(arr3, 'length', {value: 5}); |
| 632 Object.defineProperty(arr3, 'length', {value: 10, writable: false}); | 651 Object.defineProperty(arr3, 'length', {value: 10, writable: false}); |
| 633 Object.deliverChangeRecords(observer.callback); | 652 Object.deliverChangeRecords(observer.callback); |
| 634 observer.assertCallbackRecords([ | 653 observer.assertCallbackRecords([ |
| 635 { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, | 654 { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, |
| 636 { object: arr, name: '2', type: 'deleted' }, | 655 { object: arr, name: '2', type: 'deleted' }, |
| 637 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, | 656 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, |
| 638 { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, | 657 { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, |
| 639 { object: arr, name: 'length', type: 'updated', oldValue: 2 }, | 658 { object: arr, name: 'length', type: 'updated', oldValue: 2 }, |
| 640 { object: arr, name: 'length', type: 'updated', oldValue: 1 }, | 659 { object: arr, name: 'length', type: 'updated', oldValue: 1 }, |
| 641 { object: arr, name: 'length', type: 'reconfigured', oldValue: 10 }, | 660 { object: arr, name: 'length', type: 'reconfigured', oldValue: 10 }, |
| 642 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, | 661 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, |
| 643 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, | 662 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, |
| 644 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, | 663 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, |
| 645 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, | 664 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, |
| 646 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, | 665 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, |
| 647 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, | 666 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, |
| 648 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, | 667 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, |
| 668 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, |
| 669 { object: arr3, name: 'length', type: 'updated', oldValue: 2 }, |
| 670 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, |
| 649 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, | 671 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, |
| 650 ]); | 672 ]); |
| 651 | 673 |
| 652 | 674 |
| 653 // Assignments in loops (checking different IC states). | 675 // Assignments in loops (checking different IC states). |
| 654 reset(); | 676 reset(); |
| 655 var obj = {}; | 677 var obj = {}; |
| 656 Object.observe(obj, observer.callback); | 678 Object.observe(obj, observer.callback); |
| 657 for (var i = 0; i < 5; i++) { | 679 for (var i = 0; i < 5; i++) { |
| 658 obj["a" + i] = i; | 680 obj["a" + i] = i; |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 var fun = function(){}; | 940 var fun = function(){}; |
| 919 var obj = { __proto__: fun }; | 941 var obj = { __proto__: fun }; |
| 920 Object.observe(obj, observer.callback); | 942 Object.observe(obj, observer.callback); |
| 921 obj.prototype = 7; | 943 obj.prototype = 7; |
| 922 Object.deliverChangeRecords(observer.callback); | 944 Object.deliverChangeRecords(observer.callback); |
| 923 observer.assertNotCalled(); | 945 observer.assertNotCalled(); |
| 924 | 946 |
| 925 | 947 |
| 926 // Check that changes in observation status are detected in all IC states and | 948 // Check that changes in observation status are detected in all IC states and |
| 927 // in optimized code, especially in cases usually using fast elements. | 949 // in optimized code, especially in cases usually using fast elements. |
| 928 function TestFastElements(prepopulate, polymorphic, optimize) { | 950 var mutation = [ |
| 951 "a[i] = v", |
| 952 "a[i] ? ++a[i] : a[i] = v", |
| 953 "a[i] ? a[i]++ : a[i] = v", |
| 954 "a[i] ? a[i] += 1 : a[i] = v", |
| 955 "a[i] ? a[i] -= -1 : a[i] = v", |
| 956 ]; |
| 957 |
| 958 var props = [1, "1", "a"]; |
| 959 |
| 960 function TestFastElements(prop, mutation, prepopulate, polymorphic, optimize) { |
| 929 var setElement = eval( | 961 var setElement = eval( |
| 930 "(function setElement(a, i, v) { a[i] = v " + | 962 "(function setElement(a, i, v) { " + mutation + "; " + |
| 931 "/* " + prepopulate + " " + polymorphic + " " + optimize + " */" + | 963 "/* " + [].join.call(arguments, " ") + " */" + |
| 932 "})" | 964 "})" |
| 933 ); | 965 ); |
| 934 print("TestFastElements:", setElement); | 966 print("TestFastElements:", setElement); |
| 935 | 967 |
| 936 var arr = prepopulate ? [1, 2, 3, 4, 5] : [0]; | 968 var arr = prepopulate ? [1, 2, 3, 4, 5] : [0]; |
| 937 setElement(arr, 1, 210); | 969 if (prepopulate) arr[prop] = 2; // for non-element case |
| 938 setElement(arr, 1, 211); | 970 setElement(arr, prop, 3); |
| 971 setElement(arr, prop, 4); |
| 939 if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m"); | 972 if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m"); |
| 940 if (optimize) %OptimizeFunctionOnNextCall(setElement); | 973 if (optimize) %OptimizeFunctionOnNextCall(setElement); |
| 941 setElement(arr, 1, 212); | 974 setElement(arr, prop, 5); |
| 942 | 975 |
| 943 reset(); | 976 reset(); |
| 944 Object.observe(arr, observer.callback); | 977 Object.observe(arr, observer.callback); |
| 945 setElement(arr, 1, 989898); | 978 setElement(arr, prop, 989898); |
| 946 Object.deliverChangeRecords(observer.callback); | 979 Object.deliverChangeRecords(observer.callback); |
| 947 observer.assertCallbackRecords([ | 980 observer.assertCallbackRecords([ |
| 948 { object: arr, name: '1', type: 'updated', oldValue: 212 } | 981 { object: arr, name: "" + prop, type: 'updated', oldValue: 5 } |
| 949 ]); | 982 ]); |
| 950 } | 983 } |
| 951 | 984 |
| 952 for (var b1 = 0; b1 < 2; ++b1) | 985 for (var b1 = 0; b1 < 2; ++b1) |
| 953 for (var b2 = 0; b2 < 2; ++b2) | 986 for (var b2 = 0; b2 < 2; ++b2) |
| 954 for (var b3 = 0; b3 < 2; ++b3) | 987 for (var b3 = 0; b3 < 2; ++b3) |
| 955 TestFastElements(b1 != 0, b2 != 0, b3 != 0); | 988 for (var i in props) |
| 989 for (var j in mutation) |
| 990 TestFastElements(props[i], mutation[j], b1 != 0, b2 != 0, b3 != 0); |
| 956 | 991 |
| 957 function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) { | 992 |
| 993 var mutation = [ |
| 994 "a.length = v", |
| 995 "a.length += newSize - oldSize", |
| 996 "a.length -= oldSize - newSize", |
| 997 ]; |
| 998 |
| 999 var mutationByIncr = [ |
| 1000 "++a.length", |
| 1001 "a.length++", |
| 1002 ]; |
| 1003 |
| 1004 function TestFastElementsLength( |
| 1005 mutation, polymorphic, optimize, oldSize, newSize) { |
| 958 var setLength = eval( | 1006 var setLength = eval( |
| 959 "(function setLength(a, n) { a.length = n " + | 1007 "(function setLength(a, v) { " + mutation + "; " + |
| 960 "/* " + polymorphic + " " + optimize + " " + oldSize + " " + newSize + " */" | 1008 "/* " + [].join.call(arguments, " ") + " */" |
| 961 + "})" | 1009 + "})" |
| 962 ); | 1010 ); |
| 963 print("TestFastElementsLength:", setLength); | 1011 print("TestFastElementsLength:", setLength); |
| 964 | 1012 |
| 965 function array(n) { | 1013 function array(n) { |
| 966 var arr = new Array(n); | 1014 var arr = new Array(n); |
| 967 for (var i = 0; i < n; ++i) arr[i] = i; | 1015 for (var i = 0; i < n; ++i) arr[i] = i; |
| 968 return arr; | 1016 return arr; |
| 969 } | 1017 } |
| 970 | 1018 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 989 assertEquals('length', lengthRecord.name); | 1037 assertEquals('length', lengthRecord.name); |
| 990 assertEquals('updated', lengthRecord.type); | 1038 assertEquals('updated', lengthRecord.type); |
| 991 assertSame(oldSize, lengthRecord.oldValue); | 1039 assertSame(oldSize, lengthRecord.oldValue); |
| 992 } | 1040 } |
| 993 } | 1041 } |
| 994 | 1042 |
| 995 for (var b1 = 0; b1 < 2; ++b1) | 1043 for (var b1 = 0; b1 < 2; ++b1) |
| 996 for (var b2 = 0; b2 < 2; ++b2) | 1044 for (var b2 = 0; b2 < 2; ++b2) |
| 997 for (var n1 = 0; n1 < 3; ++n1) | 1045 for (var n1 = 0; n1 < 3; ++n1) |
| 998 for (var n2 = 0; n2 < 3; ++n2) | 1046 for (var n2 = 0; n2 < 3; ++n2) |
| 999 TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2); | 1047 for (var i in mutation) |
| 1048 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); |
| 1049 |
| 1050 for (var b1 = 0; b1 < 2; ++b1) |
| 1051 for (var b2 = 0; b2 < 2; ++b2) |
| 1052 for (var n = 0; n < 3; ++n) |
| 1053 for (var i in mutationByIncr) |
| 1054 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); |
| OLD | NEW |