ArrayBuffer neutering

Allen Wirfs-Brock allen at
Tue May 20 17:10:27 PDT 2014

On May 20, 2014, at 4:28 PM, Kenneth Russell wrote:

> On Tue, May 20, 2014 at 9:40 AM, Allen Wirfs-Brock
> <allen at> wrote:
>> On May 20, 2014, at 8:37 AM, Anne van Kesteren wrote:
>>> On Tue, May 20, 2014 at 5:25 PM, Allen Wirfs-Brock
>>> <allen at> wrote:
>>>> The ES6 TypedArray/ArrayBuffer spec. was written closely following the
>>>> Khronos spec. which is pretty vague about what happens when an ArrayBuffer
>>>> is neutered.
>>> If you go through
>>> and search
>>> for "neutered" it seems relatively clear. byteLength returns 0 and the
>>> other members follow from there.
>> Wow, I'm pretty sure all of those return 0 if neutered's weren't there when I used the Khronos spec. to generate the ES6 spec.
>> The change for byteLength of ArrayBuffer is trivial (and already done).
>> However, the changes for ArrayBufferView (note this doesn't actually exists in the ES spec.) and in particular the 'length' property of  the various Typed Arrays has a lot of implications to consider.
>> In ES6, (almost) all of the Array.prototype methods are available as methods of typed arrays. Do you really want all of these, if applied to an Typed Array with a neutered ArrayBuffer to act as if they were a 0 length array.  That would seem to just be a good way to obscure bugs as many of the array methods turn into no-ops when applied to 0-length arrays. With the current ES6 spec. they would throw as soon as they tried to access the underlying ArrayBuffer using the original length.
>> Also note, that ignoring this new requirement, a Typed Array's length, byteLength, and byteOffset are all constants and this fact is used in specifying the behavior of the methods that operate upon them.  If they can change (even to 0) then this can occur on any operation that can trigger side-effects.  (For example, consider calling the callback function on 'map' or similar methods).  Do we really want to dynamically reconsider changes to ;length' as opposed to simply letting throws to occur on access to the neutered ArrayBuffer?
> First, some background. When typed arrays were designed, they were
> specified with Web IDL and its ECMAScript binding. There were attempts
> during typed arrays' development to throw exceptions on some
> operations -- like out-of-range indexing -- but one by one these were
> discovered to be incompatible with either Web IDL's or ECMAScript's
> semantics like property lookup.
> When neutering was added, there were several discussions regarding how
> to detect that an object had been neutered. The current behavior of
> treating the ArrayBuffer and all of its views as though they became
> zero-length was arrived at after careful consideration of the
> alternatives. I also recall discussing this behavior in person with
> ECMAScript committee members.
> Throwing an exception upon fetching these properties from a neutered
> ArrayBuffer or view might provide nice fail-fast behavior but it's
> also incompatible with the current specification. It's likely that web
> applications using web workers, typed arrays and Transferables will
> break if this change is made.

We can make those properties all return 0, without too much impact. But that doesn't necessarily mean all the new methods (over 20) that ES6 provides for Typed Arrays can't also fail fast when applied to an TypedArray with a neutered array buffer rather than trying to pretend that it just happens to be zero length.  In particular, I don't want to have to scatter length change checks throughout thee algorithms in case one gets neutered as a side-effect of a callback or a proxy mediated access. 

What I propose is that for these new methods we will do a neutered check on entry and immediately throw a TypeError if the this value is a neutered. If not the algorithms proceeds using the current length, etc. values. If the typed array gets neutered while in the middle of one of these algorithms, a TypeError will get thrown at the point where the algorithm next tries to read or write into the ArrayBuffer. 

Oner issue, is that there is currently know way for ES code to test if an Buffer has been neutered.  That means we while I can specify these new built-ins as during the neutered test there is no way to write a ES-hosted implementation of that functionality. Why didn't you provide a isNeutered predicate?

>> Finally, I note that the current Khronos spec. doesn't provide much guidance in this regard.  The thing it has that is most similar to the other array methods is the 'subarray' method and it doesn't explicitly say anything about what happens when it is applied to a TypedArray with an underlying neutered ArrayBuffer.
> It isn't clear to me that it needs to. Starting from a view which is
> pointing to a neutered ArrayBuffer, there is no way to create a
> subarray of any nonzero length.

No, but it seems highly unlikely that anybody doing myTypedArray.subarray(5,10) actually wants to get back a 0-length array is myTypedArray happens to be neutered. 


More information about the es-discuss mailing list