Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/typedObjects/arrayTypes.js

Issue 29323484: Issue 507 - Implement lightweight array.slice() method (Closed)
Patch Set: Small improvements Created Aug. 19, 2015, 12:14 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/typedObjects.js ('k') | lib/typedObjects/objectTypes.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/typedObjects/arrayTypes.js
diff --git a/lib/typedObjects/arrayTypes.js b/lib/typedObjects/arrayTypes.js
index 03e48ba0addada242f0f263ecc28b7c8f990e8fe..051d294a1c4db2d4c2193deb77fe0b3102dd15af 100644
--- a/lib/typedObjects/arrayTypes.js
+++ b/lib/typedObjects/arrayTypes.js
@@ -17,7 +17,7 @@
"use strict";
-let {ilog2, nextPow2, alloc, dealloc, addBuffer, removeBuffer} = require("typedObjects/utils");
+let {ilog2, nextPow2, alloc, fixedPropertyDescriptor, dealloc, addBuffer, removeBuffer} = require("typedObjects/utils");
function defaultArrayConstructor()
{
@@ -26,8 +26,22 @@ function defaultArrayConstructor()
function defaultArrayDestructor()
{
- this.length = 0;
- this.size = 0;
+ if (this._copy)
+ {
+ // Carefully zero length + size if this is a slice of an array
+ Object.defineProperties(this, {
+ length: fixedPropertyDescriptor(0),
+ size: fixedPropertyDescriptor(0)
+ });
+ }
+ else
+ {
+ // Remove read-only length property for previously sliced arrays
+ delete this.length;
+
+ this.length = 0;
+ this.size = 0;
+ }
};
function createGetter(elementGetter, elementShift)
@@ -212,6 +226,52 @@ function pop()
return result;
}
+function createSlicer(elementShift)
+{
+ let {STATE_UNINITIALIZED} = require("typedObjects/objectTypes");
+
+ return function slice(start, end)
+ {
+ start = start | 0;
+ end = end | 0;
+
+ if (start < 0)
+ start = Math.max(0, this.length + start);
+ else
+ start = Math.min(start, this.length);
+
+ if (end > 0)
+ end = Math.min(0, end - this.length);
+ else
+ end = Math.max(end, -1 * this.length);
+
+ Object.defineProperties(this, {
+ length: {value: this.length, configurable: true}
+ });
+ this.retain();
+
+ let result = Object.create(this, {
+ arrayByteOffset: fixedPropertyDescriptor(
+ this.arrayByteOffset + start << elementShift
+ ),
+ length: {value: this.length - start + end, configurable: true},
+ _refCount: {value: 1, writable: true},
+ _copy: fixedPropertyDescriptor(true),
+ _state: {value: STATE_UNINITIALIZED, writable: true}
+ });
+
+ // TODO
+ // - A sliced array will have a read-only length even if all slices are
+ // released. We could fix this by keeping a count of slices, but is it
+ // worth it?
+ // - A slice of an array still keeps a reference to the array in it's
+ // __proto__ property after it's released. (We can't just replace it
+ // with null as modifying an object's prototype is apparently very slow.)
+
+ return result;
+ };
+}
+
function splice(index, count)
{
index = index | 0;
@@ -325,6 +385,7 @@ function createArrayType(elementType, typeDescriptor, meta)
typeDescriptor.shift = shift;
let elementShift = ilog2(elementType.referenceLength | 0);
+ typeDescriptor.slice = createSlicer(elementShift);
typeDescriptor.get = createGetter(elementGetter, elementShift);
typeDescriptor.set = createSetter(elementSetter, elementShift);
« no previous file with comments | « lib/typedObjects.js ('k') | lib/typedObjects/objectTypes.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld