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

Unified Diff: src/array.js

Issue 99272: Made sort on non-arrays also affect elements on the prototype, for JSC compatability. (Closed)
Patch Set: Added one more test Created 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/runtime.cc » ('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 c01c0c81333f7336ca4b89b4c772e34e9f8eef95..22885bcdad6bba2e86e9469df0ff30c8bd877dba 100644
--- a/src/array.js
+++ b/src/array.js
@@ -709,13 +709,94 @@ function ArraySort(comparefn) {
QuickSort(a, high_start, to);
}
+ // Copies elements in the range 0..length from obj's prototype chain
+ // to obj itself, if obj has holes. Returns one more than the maximal index
+ // of a prototype property.
+ function CopyFromPrototype(obj, length) {
+ var max = 0;
+ for (var o = obj.__proto__; o; o = o.__proto__) {
Erik Corry 2009/05/01 09:58:55 Can't we call o proto or something? These 1-lette
+ var indices = %GetArrayKeys(o, length);
+ if (indices.length > 0) {
+ if (indices[0] == -1) {
+ // It's an interval
Erik Corry 2009/05/01 09:58:55 Missing full stop.
+ var proto_length = indices[1];
+ for (var i = 0; i < proto_length; i++) {
+ if (!obj.hasOwnProperty(i) && o.hasOwnProperty(i)) {
+ obj[i] = o[i];
+ if (i >= max) { max = i + 1; }
+ }
+ }
+ } else {
+ for (var i = 0; i < indices.length; i++) {
+ var index = indices[i];
+ if (!IS_UNDEFINED(index) &&
+ !obj.hasOwnProperty(index) && o.hasOwnProperty(index)) {
+ obj[index] = o[index];
+ if (index >= max) { max = index + 1; }
+ }
+ }
+ }
+ }
+ }
+ return max;
+ }
+
+ // Set a value of "undefined" on all indices in the range from..to
+ // where a prototype of obj has an element. I.e., shadow all prototype
+ // elements in that range.
+ function ShadowPrototypeElements(obj, from, to) {
+ for (var o = obj.__proto__; o; o = o.__proto__) {
Erik Corry 2009/05/01 09:58:55 And here.
+ var indices = %GetArrayKeys(o, to);
+ if (indices.length > 0) {
+ if (indices[0] == -1) {
+ // It's an interval
Erik Corry 2009/05/01 09:58:55 And here.
+ var proto_length = indices[1];
+ if (proto_length > from) {
Erik Corry 2009/05/01 09:58:55 >= perhaps?
Lasse Reichstein 2009/05/01 10:05:39 Wouldn't make a difference. The next line is a loo
+ for (var i = from; i < proto_length; i++) {
+ if (o.hasOwnProperty(i)) {
+ obj[i] = void 0;
+ }
+ }
+ }
+ } else {
+ for (var i = 0; i < indices.length; i++) {
+ var index = indices[i];
+ if (!IS_UNDEFINED(index) && from <= index &&
+ o.hasOwnProperty(index)) {
+ obj[index] = void 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
var length = ToUint32(this.length);
if (length < 2) return this;
+ var is_array = IS_ARRAY(this);
+ if (!is_array) {
+ // For compatibility with JSC, we also sort elements inherited from
+ // the prototype chain on non-Array objects.
+ // We do this by copying them to this object and sorting only
+ // local elements. This is not very efficient, but sorting with
+ // inherited elements happens very, very rarely, if at all.
+ // The specification allows "implementation dependent" behavior
+ // if an element on the prototype chain has an element that
+ // might interact with sorting.
+ var max_prototype_element = CopyFromPrototype(this, length);
Erik Corry 2009/05/01 09:58:55 I think the var declaration should be hoisted out
+ }
+
var num_non_undefined = %RemoveArrayHoles(this, length);
QuickSort(this, 0, num_non_undefined);
+ if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
+ // For compatibility with JSC, we shadow any elements in the prototype
+ // chain that has become exposed by sort moving a hole to its position.
+ ShadowPrototypeElements(this, num_non_undefined, max_prototype_element);
+ }
+
return this;
}
« no previous file with comments | « no previous file | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698