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

Side by Side Diff: src/array.js

Issue 80623002: Array builtins proceed blithely on frozen arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: a.unshift() needed special care. Created 7 years 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 | « src/arm/stub-cache-arm.cc ('k') | src/builtins.cc » ('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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 throw MakeTypeError("called_on_null_or_undefined", 418 throw MakeTypeError("called_on_null_or_undefined",
419 ["Array.prototype.pop"]); 419 ["Array.prototype.pop"]);
420 } 420 }
421 421
422 var n = TO_UINT32(this.length); 422 var n = TO_UINT32(this.length);
423 if (n == 0) { 423 if (n == 0) {
424 this.length = n; 424 this.length = n;
425 return; 425 return;
426 } 426 }
427 427
428 if ($Object.isSealed(this)) {
429 throw MakeTypeError("array_functions_change_sealed",
430 ["Array.prototype.pop"]);
431 }
432
428 if (%IsObserved(this)) 433 if (%IsObserved(this))
429 return ObservedArrayPop.call(this, n); 434 return ObservedArrayPop.call(this, n);
430 435
431 n--; 436 n--;
432 var value = this[n]; 437 var value = this[n];
433 Delete(this, ToName(n), true); 438 Delete(this, ToName(n), true);
434 this.length = n; 439 this.length = n;
435 return value; 440 return value;
436 } 441 }
437 442
(...skipping 17 matching lines...) Expand all
455 } 460 }
456 461
457 // Appends the arguments to the end of the array and returns the new 462 // Appends the arguments to the end of the array and returns the new
458 // length of the array. See ECMA-262, section 15.4.4.7. 463 // length of the array. See ECMA-262, section 15.4.4.7.
459 function ArrayPush() { 464 function ArrayPush() {
460 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 465 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
461 throw MakeTypeError("called_on_null_or_undefined", 466 throw MakeTypeError("called_on_null_or_undefined",
462 ["Array.prototype.push"]); 467 ["Array.prototype.push"]);
463 } 468 }
464 469
470 var n = TO_UINT32(this.length);
471 var m = %_ArgumentsLength();
472 if (m > 0 && $Object.isSealed(this)) {
473 throw MakeTypeError("array_functions_change_sealed",
474 ["Array.prototype.push"]);
475 }
476
465 if (%IsObserved(this)) 477 if (%IsObserved(this))
466 return ObservedArrayPush.apply(this, arguments); 478 return ObservedArrayPush.apply(this, arguments);
467 479
468 var n = TO_UINT32(this.length);
469 var m = %_ArgumentsLength();
470 for (var i = 0; i < m; i++) { 480 for (var i = 0; i < m; i++) {
471 this[i+n] = %_Arguments(i); 481 this[i+n] = %_Arguments(i);
472 } 482 }
473 this.length = n + m; 483 this.length = n + m;
474 return this.length; 484 return this.length;
475 } 485 }
476 486
477 487
478 // Returns an array containing the array elements of the object followed 488 // Returns an array containing the array elements of the object followed
479 // by the array elements of each argument in order. See ECMA-262, 489 // by the array elements of each argument in order. See ECMA-262,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 ["Array.prototype.shift"]); 607 ["Array.prototype.shift"]);
598 } 608 }
599 609
600 var len = TO_UINT32(this.length); 610 var len = TO_UINT32(this.length);
601 611
602 if (len === 0) { 612 if (len === 0) {
603 this.length = 0; 613 this.length = 0;
604 return; 614 return;
605 } 615 }
606 616
617 if ($Object.isSealed(this)) {
618 throw MakeTypeError("array_functions_change_sealed",
619 ["Array.prototype.shift"]);
620 }
621
607 if (%IsObserved(this)) 622 if (%IsObserved(this))
608 return ObservedArrayShift.call(this, len); 623 return ObservedArrayShift.call(this, len);
609 624
610 var first = this[0]; 625 var first = this[0];
611 626
612 if (IS_ARRAY(this)) { 627 if (IS_ARRAY(this)) {
613 SmartMove(this, 0, 1, len, 0); 628 SmartMove(this, 0, 1, len, 0);
614 } else { 629 } else {
615 SimpleMove(this, 0, 1, len, 0); 630 SimpleMove(this, 0, 1, len, 0);
616 } 631 }
(...skipping 21 matching lines...) Expand all
638 653
639 return len + num_arguments; 654 return len + num_arguments;
640 } 655 }
641 656
642 function ArrayUnshift(arg1) { // length == 1 657 function ArrayUnshift(arg1) { // length == 1
643 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 658 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
644 throw MakeTypeError("called_on_null_or_undefined", 659 throw MakeTypeError("called_on_null_or_undefined",
645 ["Array.prototype.unshift"]); 660 ["Array.prototype.unshift"]);
646 } 661 }
647 662
663 var len = TO_UINT32(this.length);
664 var num_arguments = %_ArgumentsLength();
665 var is_sealed = $Object.isSealed(this);
666
667 if (num_arguments > 0 && is_sealed) {
668 throw MakeTypeError("array_functions_change_sealed",
669 ["Array.prototype.unshift"]);
670 }
671
648 if (%IsObserved(this)) 672 if (%IsObserved(this))
649 return ObservedArrayUnshift.apply(this, arguments); 673 return ObservedArrayUnshift.apply(this, arguments);
650 674
651 var len = TO_UINT32(this.length); 675 if (IS_ARRAY(this) && !is_sealed) {
652 var num_arguments = %_ArgumentsLength();
653
654 if (IS_ARRAY(this)) {
655 SmartMove(this, 0, 0, len, num_arguments); 676 SmartMove(this, 0, 0, len, num_arguments);
656 } else { 677 } else {
678 if (num_arguments == 0 && $Object.isFrozen(this)) {
679 // In the zero argument case, values from the prototype come into the
680 // object. This can't be allowed on frozen arrays.
681 for (var i = 0; i < len; i++) {
682 if (!this.hasOwnProperty(i) && !IS_UNDEFINED(this[i])) {
683 throw MakeTypeError("array_functions_on_frozen",
684 ["Array.prototype.shift"]);
685 }
686 }
687 }
688
657 SimpleMove(this, 0, 0, len, num_arguments); 689 SimpleMove(this, 0, 0, len, num_arguments);
658 } 690 }
659 691
660 for (var i = 0; i < num_arguments; i++) { 692 for (var i = 0; i < num_arguments; i++) {
661 this[i] = %_Arguments(i); 693 this[i] = %_Arguments(i);
662 } 694 }
663 695
664 this.length = len + num_arguments; 696 this.length = len + num_arguments;
665 697
666 return len + num_arguments; 698 return this.length;
667 } 699 }
668 700
669 701
670 function ArraySlice(start, end) { 702 function ArraySlice(start, end) {
671 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 703 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
672 throw MakeTypeError("called_on_null_or_undefined", 704 throw MakeTypeError("called_on_null_or_undefined",
673 ["Array.prototype.slice"]); 705 ["Array.prototype.slice"]);
674 } 706 }
675 707
676 var len = TO_UINT32(this.length); 708 var len = TO_UINT32(this.length);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 827
796 var num_arguments = %_ArgumentsLength(); 828 var num_arguments = %_ArgumentsLength();
797 var len = TO_UINT32(this.length); 829 var len = TO_UINT32(this.length);
798 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); 830 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
799 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, 831 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
800 start_i); 832 start_i);
801 var deleted_elements = []; 833 var deleted_elements = [];
802 deleted_elements.length = del_count; 834 deleted_elements.length = del_count;
803 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; 835 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
804 836
837 if (del_count != num_elements_to_add && $Object.isSealed(this)) {
838 throw MakeTypeError("array_functions_change_sealed",
839 ["Array.prototype.splice"]);
840 } else if (del_count > 0 && $Object.isFrozen(this)) {
841 throw MakeTypeError("array_functions_on_frozen",
842 ["Array.prototype.splice"]);
843 }
844
805 var use_simple_splice = true; 845 var use_simple_splice = true;
806 if (IS_ARRAY(this) && 846 if (IS_ARRAY(this) &&
807 num_elements_to_add !== del_count) { 847 num_elements_to_add !== del_count) {
808 // If we are only deleting/moving a few things near the end of the 848 // If we are only deleting/moving a few things near the end of the
809 // array then the simple version is going to be faster, because it 849 // array then the simple version is going to be faster, because it
810 // doesn't touch most of the array. 850 // doesn't touch most of the array.
811 var estimated_non_hole_elements = %EstimateNumberOfElements(this); 851 var estimated_non_hole_elements = %EstimateNumberOfElements(this);
812 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) { 852 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
813 use_simple_splice = false; 853 use_simple_splice = false;
814 } 854 }
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 )); 1692 ));
1653 1693
1654 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( 1694 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
1655 "join", getFunction("join", ArrayJoin), 1695 "join", getFunction("join", ArrayJoin),
1656 "pop", getFunction("pop", ArrayPop), 1696 "pop", getFunction("pop", ArrayPop),
1657 "push", getFunction("push", ArrayPush) 1697 "push", getFunction("push", ArrayPush)
1658 )); 1698 ));
1659 } 1699 }
1660 1700
1661 SetUpArray(); 1701 SetUpArray();
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/builtins.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698