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

Unified Diff: src/array.js

Issue 10453009: Fixed Array.prototype.reverse() behavior when array is frozen or array elements are not writable an… (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/messages.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/array.js
diff --git a/src/array.js b/src/array.js
index a1cc5b6a7d1a7663b10270ee07e047e54066f4fd..cb2a623a8d736e5726ebb2ba5d6160bc5295d821 100644
--- a/src/array.js
+++ b/src/array.js
@@ -486,11 +486,56 @@ function ArrayConcat(arg1) { // length == 1
}
+// Check if property is writable
+// return true if there is no property descriptor
+function PropertyIsWritable(o, p) {
+ var d = ObjectGetOwnPropertyDescriptor(o, p);
+ return !d || d.writable === true;
+}
+
+
+// Check if property is configurable
+// return true if there is no property descriptor
+function PropertyIsConfigurable(o, p) {
+ var d = ObjectGetOwnPropertyDescriptor(o, p);
+ return !d || d.configurable === true;
+}
+
+
+// Prepare and return TypeError object for array method
+function MakeTypeErrorForReadOnly(method_name) {
+ return MakeTypeError("called_on_read_only",
+ ["Array.prototype." + method_name]);
+}
+
+
+function MakeTypeErrorForNonConfigurableProperty(method_name) {
+ return MakeTypeError("cant_delete_non_configurable_property",
+ ["Array.prototype." + method_name]);
+}
+
+
+function ThrowTypeErrorIfNotWritable(method_name, a, p) {
+ if (!PropertyIsWritable(a, p)) {
+ throw MakeTypeErrorForReadOnly(method_name);
+ }
+}
+
+
+function ThrowTypeErrorIfNotConfigurable(method_name, a, p) {
+ if (!PropertyIsConfigurable(a, p)) {
+ throw MakeTypeErrorForNonConfigurableProperty(method_name);
+ }
+}
+
+
// For implementing reverse() on large, sparse arrays.
function SparseReverse(array, len) {
var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
var high_counter = keys.length - 1;
var low_counter = 0;
+ var method_name = "reverse";
+
while (low_counter <= high_counter) {
var i = keys[low_counter];
var j = keys[high_counter];
@@ -513,16 +558,25 @@ function SparseReverse(array, len) {
if (!IS_UNDEFINED(current_i) || low in array) {
var current_j = array[high];
if (!IS_UNDEFINED(current_j) || high in array) {
+ ThrowTypeErrorIfNotWritable(method_name, array, low);
array[low] = current_j;
+
+ ThrowTypeErrorIfNotWritable(method_name, array, high);
array[high] = current_i;
} else {
+ ThrowTypeErrorIfNotWritable(method_name, array, high);
array[high] = current_i;
+
+ ThrowTypeErrorIfNotConfigurable(method_name, array, low);
delete array[low];
}
} else {
var current_j = array[high];
if (!IS_UNDEFINED(current_j) || high in array) {
+ ThrowTypeErrorIfNotWritable(method_name, array, low);
array[low] = current_j;
+
+ ThrowTypeErrorIfNotConfigurable(method_name, array, high);
delete array[high];
}
}
@@ -535,29 +589,44 @@ function ArrayReverse() {
throw MakeTypeError("called_on_null_or_undefined",
["Array.prototype.reverse"]);
}
-
+
+ var method_name = "reverse";
+
+ if (ObjectIsFrozen(this)) {
+ throw MakeTypeErrorForReadOnly(method_name);
+ }
+
var j = TO_UINT32(this.length) - 1;
if (UseSparseVariant(this, j, IS_ARRAY(this))) {
SparseReverse(this, j+1);
return this;
}
-
+
for (var i = 0; i < j; i++, j--) {
var current_i = this[i];
if (!IS_UNDEFINED(current_i) || i in this) {
var current_j = this[j];
if (!IS_UNDEFINED(current_j) || j in this) {
+ ThrowTypeErrorIfNotWritable(method_name, this, i);
this[i] = current_j;
+
+ ThrowTypeErrorIfNotWritable(method_name, this, j);
this[j] = current_i;
} else {
+ ThrowTypeErrorIfNotWritable(method_name, this, j);
this[j] = current_i;
+
+ ThrowTypeErrorIfNotConfigurable(method_name, this, i);
delete this[i];
}
} else {
var current_j = this[j];
if (!IS_UNDEFINED(current_j) || j in this) {
+ ThrowTypeErrorIfNotWritable(method_name, this, i);
this[i] = current_j;
+
+ ThrowTypeErrorIfNotConfigurable(method_name, this, j);
delete this[j];
}
}
« no previous file with comments | « no previous file | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698