Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Side by Side Diff: src/array.js

Issue 240223006: Fix ToObject and Object.isSealed in four Array builtins. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-builtinbust-6.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 408 }
409 409
410 return value; 410 return value;
411 } 411 }
412 412
413 // Removes the last element from the array and returns it. See 413 // Removes the last element from the array and returns it. See
414 // ECMA-262, section 15.4.4.6. 414 // ECMA-262, section 15.4.4.6.
415 function ArrayPop() { 415 function ArrayPop() {
416 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); 416 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop");
417 417
418 var n = TO_UINT32(this.length); 418 var array = TO_OBJECT_INLINE(this);
419 var n = TO_UINT32(array.length);
419 if (n == 0) { 420 if (n == 0) {
420 this.length = n; 421 array.length = n;
421 return; 422 return;
422 } 423 }
423 424
424 if (ObjectIsSealed(this)) { 425 if (%IsObserved(array))
425 throw MakeTypeError("array_functions_change_sealed", 426 return ObservedArrayPop.call(array, n);
426 ["Array.prototype.pop"]);
427 }
428
429 if (%IsObserved(this))
430 return ObservedArrayPop.call(this, n);
431 427
432 n--; 428 n--;
433 var value = this[n]; 429 var value = array[n];
434 Delete(this, ToName(n), true); 430 Delete(array, ToName(n), true);
435 this.length = n; 431 array.length = n;
436 return value; 432 return value;
437 } 433 }
438 434
439 435
440 function ObservedArrayPush() { 436 function ObservedArrayPush() {
441 var n = TO_UINT32(this.length); 437 var n = TO_UINT32(this.length);
442 var m = %_ArgumentsLength(); 438 var m = %_ArgumentsLength();
443 439
444 try { 440 try {
445 BeginPerformSplice(this); 441 BeginPerformSplice(this);
446 for (var i = 0; i < m; i++) { 442 for (var i = 0; i < m; i++) {
447 this[i+n] = %_Arguments(i); 443 this[i+n] = %_Arguments(i);
448 } 444 }
449 var new_length = n + m; 445 var new_length = n + m;
450 this.length = new_length; 446 this.length = new_length;
451 } finally { 447 } finally {
452 EndPerformSplice(this); 448 EndPerformSplice(this);
453 EnqueueSpliceRecord(this, n, [], m); 449 EnqueueSpliceRecord(this, n, [], m);
454 } 450 }
455 451
456 return new_length; 452 return new_length;
457 } 453 }
458 454
459 // Appends the arguments to the end of the array and returns the new 455 // Appends the arguments to the end of the array and returns the new
460 // length of the array. See ECMA-262, section 15.4.4.7. 456 // length of the array. See ECMA-262, section 15.4.4.7.
461 function ArrayPush() { 457 function ArrayPush() {
462 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); 458 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
463 459
464 var n = TO_UINT32(this.length);
465 var m = %_ArgumentsLength();
466
467 if (%IsObserved(this)) 460 if (%IsObserved(this))
468 return ObservedArrayPush.apply(this, arguments); 461 return ObservedArrayPush.apply(this, arguments);
469 462
463 var array = TO_OBJECT_INLINE(this);
464 var n = TO_UINT32(array.length);
465 var m = %_ArgumentsLength();
466
470 for (var i = 0; i < m; i++) { 467 for (var i = 0; i < m; i++) {
471 // Use SetProperty rather than a direct keyed store to ensure that the store 468 // Use SetProperty rather than a direct keyed store to ensure that the store
472 // site doesn't become poisened with an elements transition KeyedStoreIC. 469 // site doesn't become poisened with an elements transition KeyedStoreIC.
473 // 470 %SetProperty(array, i+n, %_Arguments(i), 0, kStrictMode);
474 // TODO(danno): Using %SetProperty is a temporary workaround. The spec says
475 // that ToObject needs to be called for primitive values (and
476 // Runtime_SetProperty seem to ignore them).
477 %SetProperty(this, i+n, %_Arguments(i), 0, kStrictMode);
478 } 471 }
479 472
480 var new_length = n + m; 473 var new_length = n + m;
481 this.length = new_length; 474 array.length = new_length;
482 return new_length; 475 return new_length;
483 } 476 }
484 477
485 478
486 // Returns an array containing the array elements of the object followed 479 // Returns an array containing the array elements of the object followed
487 // by the array elements of each argument in order. See ECMA-262, 480 // by the array elements of each argument in order. See ECMA-262,
488 // section 15.4.4.7. 481 // section 15.4.4.7.
489 function ArrayConcat(arg1) { // length == 1 482 function ArrayConcat(arg1) { // length == 1
490 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.concat"); 483 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.concat");
491 484
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 EndPerformSplice(this); 582 EndPerformSplice(this);
590 EnqueueSpliceRecord(this, 0, [first], 0); 583 EnqueueSpliceRecord(this, 0, [first], 0);
591 } 584 }
592 585
593 return first; 586 return first;
594 } 587 }
595 588
596 function ArrayShift() { 589 function ArrayShift() {
597 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); 590 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
598 591
599 var len = TO_UINT32(this.length); 592 var array = TO_OBJECT_INLINE(this);
593 var len = TO_UINT32(array.length);
600 594
601 if (len === 0) { 595 if (len === 0) {
602 this.length = 0; 596 array.length = 0;
603 return; 597 return;
604 } 598 }
605 599
606 if (ObjectIsSealed(this)) { 600 if (ObjectIsSealed(array)) {
607 throw MakeTypeError("array_functions_change_sealed", 601 throw MakeTypeError("array_functions_change_sealed",
608 ["Array.prototype.shift"]); 602 ["Array.prototype.shift"]);
609 } 603 }
610 604
611 if (%IsObserved(this)) 605 if (%IsObserved(array))
612 return ObservedArrayShift.call(this, len); 606 return ObservedArrayShift.call(array, len);
613 607
614 var first = this[0]; 608 var first = array[0];
615 609
616 if (IS_ARRAY(this)) { 610 if (IS_ARRAY(array)) {
617 SmartMove(this, 0, 1, len, 0); 611 SmartMove(array, 0, 1, len, 0);
618 } else { 612 } else {
619 SimpleMove(this, 0, 1, len, 0); 613 SimpleMove(array, 0, 1, len, 0);
620 } 614 }
621 615
622 this.length = len - 1; 616 array.length = len - 1;
623 617
624 return first; 618 return first;
625 } 619 }
626 620
627 function ObservedArrayUnshift() { 621 function ObservedArrayUnshift() {
628 var len = TO_UINT32(this.length); 622 var len = TO_UINT32(this.length);
629 var num_arguments = %_ArgumentsLength(); 623 var num_arguments = %_ArgumentsLength();
630 624
631 try { 625 try {
632 BeginPerformSplice(this); 626 BeginPerformSplice(this);
633 SimpleMove(this, 0, 0, len, num_arguments); 627 SimpleMove(this, 0, 0, len, num_arguments);
634 for (var i = 0; i < num_arguments; i++) { 628 for (var i = 0; i < num_arguments; i++) {
635 this[i] = %_Arguments(i); 629 this[i] = %_Arguments(i);
636 } 630 }
637 var new_length = len + num_arguments; 631 var new_length = len + num_arguments;
638 this.length = new_length; 632 this.length = new_length;
639 } finally { 633 } finally {
640 EndPerformSplice(this); 634 EndPerformSplice(this);
641 EnqueueSpliceRecord(this, 0, [], num_arguments); 635 EnqueueSpliceRecord(this, 0, [], num_arguments);
642 } 636 }
643 637
644 return new_length; 638 return new_length;
645 } 639 }
646 640
647 function ArrayUnshift(arg1) { // length == 1 641 function ArrayUnshift(arg1) { // length == 1
648 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); 642 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
649 643
650 var len = TO_UINT32(this.length);
651 var num_arguments = %_ArgumentsLength();
652 var is_sealed = ObjectIsSealed(this);
653
654 if (%IsObserved(this)) 644 if (%IsObserved(this))
655 return ObservedArrayUnshift.apply(this, arguments); 645 return ObservedArrayUnshift.apply(this, arguments);
656 646
657 if (IS_ARRAY(this) && !is_sealed) { 647 var array = TO_OBJECT_INLINE(this);
658 SmartMove(this, 0, 0, len, num_arguments); 648 var len = TO_UINT32(array.length);
649 var num_arguments = %_ArgumentsLength();
650 var is_sealed = ObjectIsSealed(array);
651
652 if (IS_ARRAY(array) && !is_sealed) {
653 SmartMove(array, 0, 0, len, num_arguments);
659 } else { 654 } else {
660 SimpleMove(this, 0, 0, len, num_arguments); 655 SimpleMove(array, 0, 0, len, num_arguments);
661 } 656 }
662 657
663 for (var i = 0; i < num_arguments; i++) { 658 for (var i = 0; i < num_arguments; i++) {
664 this[i] = %_Arguments(i); 659 array[i] = %_Arguments(i);
665 } 660 }
666 661
667 var new_length = len + num_arguments; 662 var new_length = len + num_arguments;
668 this.length = new_length; 663 array.length = new_length;
669 return new_length; 664 return new_length;
670 } 665 }
671 666
672 667
673 function ArraySlice(start, end) { 668 function ArraySlice(start, end) {
674 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); 669 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
675 670
676 var len = TO_UINT32(this.length); 671 var len = TO_UINT32(this.length);
677 var start_i = TO_INTEGER(start); 672 var start_i = TO_INTEGER(start);
678 var end_i = len; 673 var end_i = len;
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 )); 1622 ));
1628 1623
1629 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( 1624 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
1630 "join", getFunction("join", ArrayJoin), 1625 "join", getFunction("join", ArrayJoin),
1631 "pop", getFunction("pop", ArrayPop), 1626 "pop", getFunction("pop", ArrayPop),
1632 "push", getFunction("push", ArrayPush) 1627 "push", getFunction("push", ArrayPush)
1633 )); 1628 ));
1634 } 1629 }
1635 1630
1636 SetUpArray(); 1631 SetUpArray();
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-builtinbust-6.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698