From 5a9d30bb86672ae3e10469adf0ca2d72d131fff2 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 10 Feb 2013 21:28:11 +0100 Subject: [PATCH] typed arrays: copy Buffer in typed array constructor Convert the Buffer to an ArrayBuffer. The typed_array.buffer property should be an ArrayBuffer to avoid confusion: a Buffer doesn't have a byteLength property and more importantly, its slice() method works subtly different. That means that before this commit: var buf = new Buffer(1); var arr = new Int8Array(buf); assert.equal(arr.buffer, buf); assert(arr.buffer instanceof Buffer); And now: var buf = new Buffer(1); var arr = new Int8Array(buf); assert.notEqual(arr.buffer, buf); assert(arr.buffer instanceof ArrayBuffer); --- src/v8_typed_array.cc | 4 +-- test/simple/test-typed-arrays.js | 60 +++++++++++++++----------------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc index 9105086b4d..2fe0196231 100644 --- a/src/v8_typed_array.cc +++ b/src/v8_typed_array.cc @@ -251,9 +251,7 @@ class TypedArray { unsigned int length = 0; unsigned int byte_offset = 0; - // [m1k3] added support for Buffer constructor - if (node::Buffer::HasInstance(args[0]) - || ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor. + if (ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor. buffer = v8::Local::Cast(args[0]); size_t buflen = buffer->GetIndexedPropertiesExternalArrayDataLength(); diff --git a/test/simple/test-typed-arrays.js b/test/simple/test-typed-arrays.js index 45547c3366..3f74c58586 100644 --- a/test/simple/test-typed-arrays.js +++ b/test/simple/test-typed-arrays.js @@ -52,29 +52,11 @@ var assert = require('assert'); assert.equal(Object.prototype.toString.call(obj), '[object DataView]'); }); -// initialize a zero-filled buffer -var buffer = new Buffer(16); -buffer.fill(0); - -// only one of these instantiations should succeed, as the other ones will be -// unaligned -var errors = 0; -var offset; -for (var i = 0; i < 8; i++) { - try { - new Float64Array(buffer, i); - offset = i; - } catch (e) { - errors += 1; - } -} - -assert.equal(errors, 7); - -var uint8 = new Uint8Array(buffer, offset); -var uint16 = new Uint16Array(buffer, offset); -var uint16slice = new Uint16Array(buffer, offset + 2, 2); -var uint32 = new Uint32Array(buffer, offset); +var buffer = new ArrayBuffer(16); +var uint8 = new Uint8Array(buffer); +var uint16 = new Uint16Array(buffer); +var uint16slice = new Uint16Array(buffer, 2, 2); +var uint32 = new Uint32Array(buffer); assert.equal(uint8.BYTES_PER_ELEMENT, 1); assert.equal(uint16.BYTES_PER_ELEMENT, 2); @@ -82,14 +64,14 @@ assert.equal(uint16slice.BYTES_PER_ELEMENT, 2); assert.equal(uint32.BYTES_PER_ELEMENT, 4); // now change the underlying buffer -buffer[offset ] = 0x08; -buffer[offset + 1] = 0x09; -buffer[offset + 2] = 0x0a; -buffer[offset + 3] = 0x0b; -buffer[offset + 4] = 0x0c; -buffer[offset + 5] = 0x0d; -buffer[offset + 6] = 0x0e; -buffer[offset + 7] = 0x0f; +buffer[0] = 0x08; +buffer[1] = 0x09; +buffer[2] = 0x0a; +buffer[3] = 0x0b; +buffer[4] = 0x0c; +buffer[5] = 0x0d; +buffer[6] = 0x0e; +buffer[7] = 0x0f; /* This is what we expect the variables to look like at this point (on @@ -202,6 +184,22 @@ assert.throws(function() { assert.equal(view.getUint16(0), 1); })(); +(function() { + // Typed array should make a copy of the buffer object, i.e. it's not shared. + var b = new Buffer([0]); + var a = new Uint8Array(b); + assert.notEqual(a.buffer, b); + assert.equal(a[0], 0); + assert.equal(b[0], 0); + a[0] = 1; + assert.equal(a[0], 1); + assert.equal(b[0], 0); + a[0] = 0; + b[0] = 1; + assert.equal(a[0], 0); + assert.equal(b[0], 1); +})(); + (function() { // Backing store should not be shared. var a = new Uint8Array(1);