Skip to content

Commit d7cfd0c

Browse files
bnoordhuisdanielleadams
authored andcommitted
v8: serialize BigInt64Array and BigUint64Array
Teach the serializer about BigInt64Array and BigUint64Array. I open-coded the type-to-index mapper to stay compatible with the current wire format without undue code gymnastics. PR-URL: #43571 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 0aa255a commit d7cfd0c

File tree

2 files changed

+54
-34
lines changed

2 files changed

+54
-34
lines changed

lib/v8.js

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616

1717
const {
1818
Array,
19-
ArrayBuffer,
20-
ArrayPrototypeForEach,
21-
ArrayPrototypePush,
19+
BigInt64Array,
20+
BigUint64Array,
2221
DataView,
2322
Error,
2423
Float32Array,
@@ -27,7 +26,6 @@ const {
2726
Int32Array,
2827
Int8Array,
2928
ObjectPrototypeToString,
30-
SafeMap,
3129
Uint16Array,
3230
Uint32Array,
3331
Uint8Array,
@@ -247,29 +245,40 @@ Deserializer.prototype.readRawBytes = function readRawBytes(length) {
247245
length);
248246
};
249247

250-
/* Keep track of how to handle different ArrayBufferViews.
251-
* The default Serializer for Node does not use the V8 methods for serializing
252-
* those objects because Node's `Buffer` objects use pooled allocation in many
253-
* cases, and their underlying `ArrayBuffer`s would show up in the
254-
* serialization. Because a) those may contain sensitive data and the user
255-
* may not be aware of that and b) they are often much larger than the `Buffer`
256-
* itself, custom serialization is applied. */
257-
const arrayBufferViewTypes = [Int8Array, Uint8Array, Uint8ClampedArray,
258-
Int16Array, Uint16Array, Int32Array, Uint32Array,
259-
Float32Array, Float64Array, DataView];
260-
261-
const arrayBufferViewTypeToIndex = new SafeMap();
262-
263-
{
264-
const dummy = new ArrayBuffer();
265-
ArrayPrototypeForEach(arrayBufferViewTypes, (ctor, i) => {
266-
const tag = ObjectPrototypeToString(new ctor(dummy));
267-
arrayBufferViewTypeToIndex.set(tag, i);
268-
});
248+
function arrayBufferViewTypeToIndex(abView) {
249+
const type = ObjectPrototypeToString(abView);
250+
if (type === '[object Int8Array]') return 0;
251+
if (type === '[object Uint8Array]') return 1;
252+
if (type === '[object Uint8ClampedArray]') return 2;
253+
if (type === '[object Int16Array]') return 3;
254+
if (type === '[object Uint16Array]') return 4;
255+
if (type === '[object Int32Array]') return 5;
256+
if (type === '[object Uint32Array]') return 6;
257+
if (type === '[object Float32Array]') return 7;
258+
if (type === '[object Float64Array]') return 8;
259+
if (type === '[object DataView]') return 9;
260+
// Index 10 is FastBuffer.
261+
if (type === '[object BigInt64Array]') return 11;
262+
if (type === '[object BigUint64Array]') return 12;
263+
return -1;
269264
}
270265

271-
const bufferConstructorIndex =
272-
ArrayPrototypePush(arrayBufferViewTypes, FastBuffer) - 1;
266+
function arrayBufferViewIndexToType(index) {
267+
if (index === 0) return Int8Array;
268+
if (index === 1) return Uint8Array;
269+
if (index === 2) return Uint8ClampedArray;
270+
if (index === 3) return Int16Array;
271+
if (index === 4) return Uint16Array;
272+
if (index === 5) return Int32Array;
273+
if (index === 6) return Uint32Array;
274+
if (index === 7) return Float32Array;
275+
if (index === 8) return Float64Array;
276+
if (index === 9) return DataView;
277+
if (index === 10) return FastBuffer;
278+
if (index === 11) return BigInt64Array;
279+
if (index === 12) return BigUint64Array;
280+
return undefined;
281+
}
273282

274283
class DefaultSerializer extends Serializer {
275284
constructor() {
@@ -285,14 +294,17 @@ class DefaultSerializer extends Serializer {
285294
* @returns {void}
286295
*/
287296
_writeHostObject(abView) {
288-
let i = 0;
289-
if (abView.constructor === Buffer) {
290-
i = bufferConstructorIndex;
291-
} else {
292-
const tag = ObjectPrototypeToString(abView);
293-
i = arrayBufferViewTypeToIndex.get(tag);
294-
295-
if (i === undefined) {
297+
// Keep track of how to handle different ArrayBufferViews. The default
298+
// Serializer for Node does not use the V8 methods for serializing those
299+
// objects because Node's `Buffer` objects use pooled allocation in many
300+
// cases, and their underlying `ArrayBuffer`s would show up in the
301+
// serialization. Because a) those may contain sensitive data and the user
302+
// may not be aware of that and b) they are often much larger than the
303+
// `Buffer` itself, custom serialization is applied.
304+
let i = 10; // FastBuffer
305+
if (abView.constructor !== Buffer) {
306+
i = arrayBufferViewTypeToIndex(abView);
307+
if (i === -1) {
296308
throw new this._getDataCloneError(
297309
`Unserializable host object: ${inspect(abView)}`);
298310
}
@@ -313,7 +325,7 @@ class DefaultDeserializer extends Deserializer {
313325
*/
314326
_readHostObject() {
315327
const typeIndex = this.readUint32();
316-
const ctor = arrayBufferViewTypes[typeIndex];
328+
const ctor = arrayBufferViewIndexToType(typeIndex);
317329
const byteLength = this.readUint32();
318330
const byteOffset = this._readRawBytes(byteLength);
319331
const BYTES_PER_ELEMENT = ctor.BYTES_PER_ELEMENT || 1;

test/parallel/test-v8-serdes.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,18 @@ circular.circular = circular;
1414
const objects = [
1515
{ foo: 'bar' },
1616
{ bar: 'baz' },
17+
new Int8Array([1, 2, 3, 4]),
1718
new Uint8Array([1, 2, 3, 4]),
19+
new Int16Array([1, 2, 3, 4]),
20+
new Uint16Array([1, 2, 3, 4]),
21+
new Int32Array([1, 2, 3, 4]),
1822
new Uint32Array([1, 2, 3, 4]),
23+
new Float32Array([1, 2, 3, 4]),
24+
new Float64Array([1, 2, 3, 4]),
1925
new DataView(new ArrayBuffer(42)),
2026
Buffer.from([1, 2, 3, 4]),
27+
new BigInt64Array([42n]),
28+
new BigUint64Array([42n]),
2129
undefined,
2230
null,
2331
42,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy