|
16 | 16 |
|
17 | 17 | const { |
18 | 18 | Array, |
19 | | - ArrayBuffer, |
20 | | - ArrayPrototypeForEach, |
21 | | - ArrayPrototypePush, |
| 19 | + BigInt64Array, |
| 20 | + BigUint64Array, |
22 | 21 | DataView, |
23 | 22 | Error, |
24 | 23 | Float32Array, |
@@ -27,7 +26,6 @@ const { |
27 | 26 | Int32Array, |
28 | 27 | Int8Array, |
29 | 28 | ObjectPrototypeToString, |
30 | | - SafeMap, |
31 | 29 | Uint16Array, |
32 | 30 | Uint32Array, |
33 | 31 | Uint8Array, |
@@ -247,29 +245,40 @@ Deserializer.prototype.readRawBytes = function readRawBytes(length) { |
247 | 245 | length); |
248 | 246 | }; |
249 | 247 |
|
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; |
269 | 264 | } |
270 | 265 |
|
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 | +} |
273 | 282 |
|
274 | 283 | class DefaultSerializer extends Serializer { |
275 | 284 | constructor() { |
@@ -285,14 +294,17 @@ class DefaultSerializer extends Serializer { |
285 | 294 | * @returns {void} |
286 | 295 | */ |
287 | 296 | _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) { |
296 | 308 | throw new this._getDataCloneError( |
297 | 309 | `Unserializable host object: ${inspect(abView)}`); |
298 | 310 | } |
@@ -313,7 +325,7 @@ class DefaultDeserializer extends Deserializer { |
313 | 325 | */ |
314 | 326 | _readHostObject() { |
315 | 327 | const typeIndex = this.readUint32(); |
316 | | - const ctor = arrayBufferViewTypes[typeIndex]; |
| 328 | + const ctor = arrayBufferViewIndexToType(typeIndex); |
317 | 329 | const byteLength = this.readUint32(); |
318 | 330 | const byteOffset = this._readRawBytes(byteLength); |
319 | 331 | const BYTES_PER_ELEMENT = ctor.BYTES_PER_ELEMENT || 1; |
|