diff --git a/lib/index.js b/lib/index.js index 0229347..5884336 100644 --- a/lib/index.js +++ b/lib/index.js @@ -338,9 +338,6 @@ function isArrayBufferDetached(value) { exports.ArrayBuffer = (value, options = {}) => { if (!isNonSharedArrayBuffer(value)) { - if (options.allowShared && !isSharedArrayBuffer(value)) { - throw makeException(TypeError, "is not an ArrayBuffer or SharedArrayBuffer", options); - } throw makeException(TypeError, "is not an ArrayBuffer", options); } if (isArrayBufferDetached(value)) { @@ -350,6 +347,17 @@ exports.ArrayBuffer = (value, options = {}) => { return value; }; +exports.SharedArrayBuffer = (value, options = {}) => { + if (!isSharedArrayBuffer(value)) { + throw makeException(TypeError, "is not a SharedArrayBuffer", options); + } + if (isArrayBufferDetached(value)) { + throw makeException(TypeError, "is a detached SharedArrayBuffer", options); + } + + return value; +}; + const dvByteLengthGetter = Object.getOwnPropertyDescriptor(DataView.prototype, "byteLength").get; exports.DataView = (value, options = {}) => { @@ -358,15 +366,7 @@ exports.DataView = (value, options = {}) => { } catch (e) { throw makeException(TypeError, "is not a DataView", options); } - - if (!options.allowShared && isSharedArrayBuffer(value.buffer)) { - throw makeException(TypeError, "is backed by a SharedArrayBuffer, which is not allowed", options); - } - if (isArrayBufferDetached(value.buffer)) { - throw makeException(TypeError, "is backed by a detached ArrayBuffer", options); - } - - return value; + return exports.ArrayBufferView(value, options); }; // Returns the unforgeable `TypedArray` constructor name or `undefined`, @@ -394,14 +394,7 @@ const typedArrayNameGetter = Object.getOwnPropertyDescriptor( if (!ArrayBuffer.isView(value) || typedArrayNameGetter.call(value) !== name) { throw makeException(TypeError, `is not ${article} ${name} object`, options); } - if (!options.allowShared && isSharedArrayBuffer(value.buffer)) { - throw makeException(TypeError, "is a view on a SharedArrayBuffer, which is not allowed", options); - } - if (isArrayBufferDetached(value.buffer)) { - throw makeException(TypeError, "is a view on a detached ArrayBuffer", options); - } - - return value; + return exports.ArrayBufferView(value, options); }; }); @@ -424,27 +417,20 @@ exports.ArrayBufferView = (value, options = {}) => { exports.BufferSource = (value, options = {}) => { if (ArrayBuffer.isView(value)) { - if (!options.allowShared && isSharedArrayBuffer(value.buffer)) { - throw makeException(TypeError, "is a view on a SharedArrayBuffer, which is not allowed", options); - } - - if (isArrayBufferDetached(value.buffer)) { - throw makeException(TypeError, "is a view on a detached ArrayBuffer", options); - } - return value; + return exports.ArrayBufferView(value, options); } - if (!options.allowShared && !isNonSharedArrayBuffer(value)) { - throw makeException(TypeError, "is not an ArrayBuffer or a view on one", options); + if (isNonSharedArrayBuffer(value)) { + return exports.ArrayBuffer(value, options); + } else if (options.allowShared && isSharedArrayBuffer(value)) { + return exports.SharedArrayBuffer(value, options); } - if (options.allowShared && !isSharedArrayBuffer(value) && !isNonSharedArrayBuffer(value)) { + + if (options.allowShared) { throw makeException(TypeError, "is not an ArrayBuffer, SharedArrayBuffer, or a view on one", options); + } else { + throw makeException(TypeError, "is not an ArrayBuffer or a view on one", options); } - if (isArrayBufferDetached(value)) { - throw makeException(TypeError, "is a detached ArrayBuffer", options); - } - - return value; }; exports.DOMTimeStamp = exports["unsigned long long"]; diff --git a/test/buffer-source.js b/test/buffer-source.js index 1dd6b48..b8fdd71 100644 --- a/test/buffer-source.js +++ b/test/buffer-source.js @@ -111,6 +111,13 @@ if (typeof SharedArrayBuffer === "function") { label: "SharedArrayBuffer same realm", creator: () => new SharedArrayBuffer(0) }); + bufferSourceCreators.push({ + typeName: "SharedArrayBuffer", + isShared: true, + isDetached: false, + label: "SharedArrayBuffer different realm", + creator: () => vm.runInContext(`new SharedArrayBuffer(0)`, differentRealm) + }); } for (const constructor of bufferSourceConstructors) { @@ -213,6 +220,27 @@ for (const type of bufferSourceConstructors) { }); } +if (typeof SharedArrayBuffer === "function") { + const typeName = "SharedArrayBuffer"; + const sut = conversions[typeName]; + + describe(`WebIDL SharedArrayBuffer type`, () => { + for (const innerType of bufferSourceCreators) { + const testFunction = + innerType.typeName === typeName && + innerType.isShared && + !innerType.isDetached && + !innerType.isForged ? + testOk : + testNotOk; + + testFunction(innerType.label, sut, innerType.creator); + } + + commonNotOk(sut); + }); +} + describe("WebIDL ArrayBufferView type", () => { const sut = conversions.ArrayBufferView;