| 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 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 var arrays = new InternalArray(1 + arg_count); | 479 var arrays = new InternalArray(1 + arg_count); |
| 480 arrays[0] = array; | 480 arrays[0] = array; |
| 481 for (var i = 0; i < arg_count; i++) { | 481 for (var i = 0; i < arg_count; i++) { |
| 482 arrays[i + 1] = %_Arguments(i); | 482 arrays[i + 1] = %_Arguments(i); |
| 483 } | 483 } |
| 484 | 484 |
| 485 return %ArrayConcat(arrays); | 485 return %ArrayConcat(arrays); |
| 486 } | 486 } |
| 487 | 487 |
| 488 | 488 |
| 489 // Check if property is writable |
| 490 // return true if there is no property descriptor |
| 491 function PropertyIsWritable(o, p) { |
| 492 var d = ObjectGetOwnPropertyDescriptor(o, p); |
| 493 return !d || d.writable === true; |
| 494 } |
| 495 |
| 496 |
| 497 // Check if property is configurable |
| 498 // return true if there is no property descriptor |
| 499 function PropertyIsConfigurable(o, p) { |
| 500 var d = ObjectGetOwnPropertyDescriptor(o, p); |
| 501 return !d || d.configurable === true; |
| 502 } |
| 503 |
| 504 |
| 505 // Prepare and return TypeError object for array method |
| 506 function MakeTypeErrorForReadOnly(method_name) { |
| 507 return MakeTypeError("called_on_read_only", |
| 508 ["Array.prototype." + method_name]); |
| 509 } |
| 510 |
| 511 |
| 512 function MakeTypeErrorForNonConfigurableProperty(method_name) { |
| 513 return MakeTypeError("cant_delete_non_configurable_property", |
| 514 ["Array.prototype." + method_name]); |
| 515 } |
| 516 |
| 517 |
| 518 function ThrowTypeErrorIfNotWritable(method_name, a, p) { |
| 519 if (!PropertyIsWritable(a, p)) { |
| 520 throw MakeTypeErrorForReadOnly(method_name); |
| 521 } |
| 522 } |
| 523 |
| 524 |
| 525 function ThrowTypeErrorIfNotConfigurable(method_name, a, p) { |
| 526 if (!PropertyIsConfigurable(a, p)) { |
| 527 throw MakeTypeErrorForNonConfigurableProperty(method_name); |
| 528 } |
| 529 } |
| 530 |
| 531 |
| 489 // For implementing reverse() on large, sparse arrays. | 532 // For implementing reverse() on large, sparse arrays. |
| 490 function SparseReverse(array, len) { | 533 function SparseReverse(array, len) { |
| 491 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); | 534 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); |
| 492 var high_counter = keys.length - 1; | 535 var high_counter = keys.length - 1; |
| 493 var low_counter = 0; | 536 var low_counter = 0; |
| 537 var method_name = "reverse"; |
| 538 |
| 494 while (low_counter <= high_counter) { | 539 while (low_counter <= high_counter) { |
| 495 var i = keys[low_counter]; | 540 var i = keys[low_counter]; |
| 496 var j = keys[high_counter]; | 541 var j = keys[high_counter]; |
| 497 | 542 |
| 498 var j_complement = len - j - 1; | 543 var j_complement = len - j - 1; |
| 499 var low, high; | 544 var low, high; |
| 500 | 545 |
| 501 if (j_complement <= i) { | 546 if (j_complement <= i) { |
| 502 high = j; | 547 high = j; |
| 503 while (keys[--high_counter] == j) { } | 548 while (keys[--high_counter] == j) { } |
| 504 low = j_complement; | 549 low = j_complement; |
| 505 } | 550 } |
| 506 if (j_complement >= i) { | 551 if (j_complement >= i) { |
| 507 low = i; | 552 low = i; |
| 508 while (keys[++low_counter] == i) { } | 553 while (keys[++low_counter] == i) { } |
| 509 high = len - i - 1; | 554 high = len - i - 1; |
| 510 } | 555 } |
| 511 | 556 |
| 512 var current_i = array[low]; | 557 var current_i = array[low]; |
| 513 if (!IS_UNDEFINED(current_i) || low in array) { | 558 if (!IS_UNDEFINED(current_i) || low in array) { |
| 514 var current_j = array[high]; | 559 var current_j = array[high]; |
| 515 if (!IS_UNDEFINED(current_j) || high in array) { | 560 if (!IS_UNDEFINED(current_j) || high in array) { |
| 561 ThrowTypeErrorIfNotWritable(method_name, array, low); |
| 516 array[low] = current_j; | 562 array[low] = current_j; |
| 563 |
| 564 ThrowTypeErrorIfNotWritable(method_name, array, high); |
| 517 array[high] = current_i; | 565 array[high] = current_i; |
| 518 } else { | 566 } else { |
| 567 ThrowTypeErrorIfNotWritable(method_name, array, high); |
| 519 array[high] = current_i; | 568 array[high] = current_i; |
| 569 |
| 570 ThrowTypeErrorIfNotConfigurable(method_name, array, low); |
| 520 delete array[low]; | 571 delete array[low]; |
| 521 } | 572 } |
| 522 } else { | 573 } else { |
| 523 var current_j = array[high]; | 574 var current_j = array[high]; |
| 524 if (!IS_UNDEFINED(current_j) || high in array) { | 575 if (!IS_UNDEFINED(current_j) || high in array) { |
| 576 ThrowTypeErrorIfNotWritable(method_name, array, low); |
| 525 array[low] = current_j; | 577 array[low] = current_j; |
| 578 |
| 579 ThrowTypeErrorIfNotConfigurable(method_name, array, high); |
| 526 delete array[high]; | 580 delete array[high]; |
| 527 } | 581 } |
| 528 } | 582 } |
| 529 } | 583 } |
| 530 } | 584 } |
| 531 | 585 |
| 532 | 586 |
| 533 function ArrayReverse() { | 587 function ArrayReverse() { |
| 534 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 588 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
| 535 throw MakeTypeError("called_on_null_or_undefined", | 589 throw MakeTypeError("called_on_null_or_undefined", |
| 536 ["Array.prototype.reverse"]); | 590 ["Array.prototype.reverse"]); |
| 537 } | 591 } |
| 538 | 592 |
| 593 var method_name = "reverse"; |
| 594 |
| 595 if (ObjectIsFrozen(this)) { |
| 596 throw MakeTypeErrorForReadOnly(method_name); |
| 597 } |
| 598 |
| 539 var j = TO_UINT32(this.length) - 1; | 599 var j = TO_UINT32(this.length) - 1; |
| 540 | 600 |
| 541 if (UseSparseVariant(this, j, IS_ARRAY(this))) { | 601 if (UseSparseVariant(this, j, IS_ARRAY(this))) { |
| 542 SparseReverse(this, j+1); | 602 SparseReverse(this, j+1); |
| 543 return this; | 603 return this; |
| 544 } | 604 } |
| 545 | 605 |
| 546 for (var i = 0; i < j; i++, j--) { | 606 for (var i = 0; i < j; i++, j--) { |
| 547 var current_i = this[i]; | 607 var current_i = this[i]; |
| 548 if (!IS_UNDEFINED(current_i) || i in this) { | 608 if (!IS_UNDEFINED(current_i) || i in this) { |
| 549 var current_j = this[j]; | 609 var current_j = this[j]; |
| 550 if (!IS_UNDEFINED(current_j) || j in this) { | 610 if (!IS_UNDEFINED(current_j) || j in this) { |
| 611 ThrowTypeErrorIfNotWritable(method_name, this, i); |
| 551 this[i] = current_j; | 612 this[i] = current_j; |
| 613 |
| 614 ThrowTypeErrorIfNotWritable(method_name, this, j); |
| 552 this[j] = current_i; | 615 this[j] = current_i; |
| 553 } else { | 616 } else { |
| 617 ThrowTypeErrorIfNotWritable(method_name, this, j); |
| 554 this[j] = current_i; | 618 this[j] = current_i; |
| 619 |
| 620 ThrowTypeErrorIfNotConfigurable(method_name, this, i); |
| 555 delete this[i]; | 621 delete this[i]; |
| 556 } | 622 } |
| 557 } else { | 623 } else { |
| 558 var current_j = this[j]; | 624 var current_j = this[j]; |
| 559 if (!IS_UNDEFINED(current_j) || j in this) { | 625 if (!IS_UNDEFINED(current_j) || j in this) { |
| 626 ThrowTypeErrorIfNotWritable(method_name, this, i); |
| 560 this[i] = current_j; | 627 this[i] = current_j; |
| 628 |
| 629 ThrowTypeErrorIfNotConfigurable(method_name, this, j); |
| 561 delete this[j]; | 630 delete this[j]; |
| 562 } | 631 } |
| 563 } | 632 } |
| 564 } | 633 } |
| 565 return this; | 634 return this; |
| 566 } | 635 } |
| 567 | 636 |
| 568 | 637 |
| 569 function ArrayShift() { | 638 function ArrayShift() { |
| 570 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 639 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
| (...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 // exposed to user code. | 1593 // exposed to user code. |
| 1525 // Adding only the functions that are actually used. | 1594 // Adding only the functions that are actually used. |
| 1526 SetUpLockedPrototype(InternalArray, $Array(), $Array( | 1595 SetUpLockedPrototype(InternalArray, $Array(), $Array( |
| 1527 "join", getFunction("join", ArrayJoin), | 1596 "join", getFunction("join", ArrayJoin), |
| 1528 "pop", getFunction("pop", ArrayPop), | 1597 "pop", getFunction("pop", ArrayPop), |
| 1529 "push", getFunction("push", ArrayPush) | 1598 "push", getFunction("push", ArrayPush) |
| 1530 )); | 1599 )); |
| 1531 } | 1600 } |
| 1532 | 1601 |
| 1533 SetUpArray(); | 1602 SetUpArray(); |
| OLD | NEW |