From 0ef51c79b7dcd6ae5890b2dce4304be7c8ebe314 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 4 Jan 2023 22:57:33 -0800 Subject: [PATCH] [New] add support for `SharedArrayBuffer` --- .eslintrc | 2 +- index.js | 32 +++++++++++++++++---------- package.json | 1 + test/cmp.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 12 deletions(-) diff --git a/.eslintrc b/.eslintrc index eab8409..411501b 100755 --- a/.eslintrc +++ b/.eslintrc @@ -25,7 +25,7 @@ "files": "example/**", "rules": { "no-console": 0, - "no-magic-numbers": 0, + "no-magic-numbers": 0, } }, { diff --git a/index.js b/index.js index 9fc94a9..dcf8419 100644 --- a/index.js +++ b/index.js @@ -1,24 +1,26 @@ 'use strict'; -var objectKeys = require('object-keys'); -var isArguments = require('is-arguments'); -var is = require('object-is'); -var isRegex = require('is-regex'); +var assign = require('object.assign'); +var callBound = require('call-bind/callBound'); var flags = require('regexp.prototype.flags'); +var GetIntrinsic = require('get-intrinsic'); +var getIterator = require('es-get-iterator'); +var getSideChannel = require('side-channel'); +var is = require('object-is'); +var isArguments = require('is-arguments'); var isArray = require('isarray'); +var isArrayBuffer = require('is-array-buffer'); var isDate = require('is-date-object'); +var isRegex = require('is-regex'); +var isSharedArrayBuffer = require('is-shared-array-buffer'); +var objectKeys = require('object-keys'); var whichBoxedPrimitive = require('which-boxed-primitive'); -var GetIntrinsic = require('get-intrinsic'); -var callBound = require('call-bind/callBound'); var whichCollection = require('which-collection'); -var getIterator = require('es-get-iterator'); -var getSideChannel = require('side-channel'); var whichTypedArray = require('which-typed-array'); -var assign = require('object.assign'); -var isArrayBuffer = require('is-array-buffer'); -var byteLength = callBound('%ArrayBuffer.prototype.byteLength%', true) +var byteLength = callBound('ArrayBuffer.prototype.byteLength', true) || function byteLength(ab) { return ab.byteLength; }; // in node < 0.11, byteLength is an own nonconfigurable property +var sabByteLength = callBound('SharedArrayBuffer.prototype.byteLength', true); var $getTime = callBound('Date.prototype.getTime'); var gPO = Object.getPrototypeOf; @@ -335,6 +337,14 @@ function objEquiv(a, b, opts, channel) { return typeof Uint8Array === 'function' && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel); } + var aIsSAB = isSharedArrayBuffer(a); + var bIsSAB = isSharedArrayBuffer(b); + if (aIsSAB !== bIsSAB) { return false; } + if (aIsSAB || bIsSAB) { // && would work too, because both are true or both false here + if (sabByteLength(a) !== sabByteLength(b)) { return false; } + return typeof Uint8Array === 'function' && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel); + } + if (typeof a !== typeof b) { return false; } var ka = objectKeys(a); diff --git a/package.json b/package.json index 1b04a8e..d4c7daf 100755 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "is-array-buffer": "^3.0.1", "is-date-object": "^1.0.5", "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", "isarray": "^2.0.5", "object-is": "^1.1.5", "object-keys": "^1.1.1", diff --git a/test/cmp.js b/test/cmp.js index c4f5376..891b9ff 100644 --- a/test/cmp.js +++ b/test/cmp.js @@ -1236,5 +1236,66 @@ test('TypedArrays', { skip: !hasTypedArrays }, function (t) { st.end(); }); + t.test('SharedArrayBuffers', { skip: typeof SharedArrayBuffer !== 'function' }, function (st) { + var buffer1 = new SharedArrayBuffer(8); // initial value of 0's + var buffer2 = new SharedArrayBuffer(8); // initial value of 0's + + var view1 = new Int8Array(buffer1); + var view2 = new Int8Array(buffer2); + + st.deepEqualTest( + view1, + view2, + 'Int8Arrays of similar SharedArrayBuffers', + true, + true + ); + + st.deepEqualTest( + buffer1, + buffer2, + 'similar SharedArrayBuffers', + true, + true + ); + + for (var i = 0; i < view1.byteLength; i += 1) { + view1[i] = 9; // change all values to 9's + } + + st.deepEqualTest( + view1, + view2, + 'Int8Arrays of different SharedArrayBuffers', + false, + false + ); + + st.deepEqualTest( + buffer1, + buffer2, + 'different SharedArrayBuffers', + false, + false + ); + + t.test('lies about byteLength', { skip: !('byteLength' in SharedArrayBuffer.prototype) }, function (s2t) { + var empty4 = new SharedArrayBuffer(4); + var empty6 = new SharedArrayBuffer(6); + Object.defineProperty(empty6, 'byteLength', { value: 4 }); + + s2t.deepEqualTest( + empty4, + empty6, + 'different-length SharedArrayBuffers, one lying', + false, + false + ); + s2t.end(); + }); + + st.end(); + }); + t.end(); });