mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 19:08:15 +00:00
fix(ext): internal structuredClone
for ArrayBuffer
and TypedArray
subclasses (#17431)
This commit is contained in:
parent
04ba709b6e
commit
266915d5ce
6 changed files with 133 additions and 25 deletions
|
@ -14,13 +14,32 @@
|
|||
const {
|
||||
ArrayBuffer,
|
||||
ArrayBufferPrototype,
|
||||
ArrayBufferPrototypeGetByteLength,
|
||||
ArrayBufferPrototypeSlice,
|
||||
ArrayBufferIsView,
|
||||
DataViewPrototype,
|
||||
DataView,
|
||||
DataViewPrototypeGetBuffer,
|
||||
DataViewPrototypeGetByteLength,
|
||||
DataViewPrototypeGetByteOffset,
|
||||
ObjectPrototypeIsPrototypeOf,
|
||||
TypedArrayPrototypeSlice,
|
||||
TypedArrayPrototypeGetBuffer,
|
||||
TypedArrayPrototypeGetByteOffset,
|
||||
TypedArrayPrototypeGetLength,
|
||||
TypedArrayPrototypeGetSymbolToStringTag,
|
||||
TypeErrorPrototype,
|
||||
WeakMap,
|
||||
WeakMapPrototypeSet,
|
||||
Int8Array,
|
||||
Int16Array,
|
||||
Int32Array,
|
||||
BigInt64Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Uint16Array,
|
||||
Uint32Array,
|
||||
BigUint64Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
} = window.__bootstrap.primordials;
|
||||
|
||||
const objectCloneMemo = new WeakMap();
|
||||
|
@ -32,14 +51,15 @@
|
|||
_cloneConstructor,
|
||||
) {
|
||||
// this function fudges the return type but SharedArrayBuffer is disabled for a while anyway
|
||||
return TypedArrayPrototypeSlice(
|
||||
return ArrayBufferPrototypeSlice(
|
||||
srcBuffer,
|
||||
srcByteOffset,
|
||||
srcByteOffset + srcLength,
|
||||
);
|
||||
}
|
||||
|
||||
/** Clone a value in a similar way to structured cloning. It is similar to a
|
||||
// TODO(petamoriken): Resizable ArrayBuffer support in the future
|
||||
/** Clone a value in a similar way to structured cloning. It is similar to a
|
||||
* StructureDeserialize(StructuredSerialize(...)). */
|
||||
function structuredClone(value) {
|
||||
// Performance optimization for buffers, otherwise
|
||||
|
@ -48,28 +68,64 @@
|
|||
const cloned = cloneArrayBuffer(
|
||||
value,
|
||||
0,
|
||||
value.byteLength,
|
||||
ArrayBufferPrototypeGetByteLength(value),
|
||||
ArrayBuffer,
|
||||
);
|
||||
WeakMapPrototypeSet(objectCloneMemo, value, cloned);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
if (ArrayBufferIsView(value)) {
|
||||
const clonedBuffer = structuredClone(value.buffer);
|
||||
// Use DataViewConstructor type purely for type-checking, can be a
|
||||
// DataView or TypedArray. They use the same constructor signature,
|
||||
// only DataView has a length in bytes and TypedArrays use a length in
|
||||
// terms of elements, so we adjust for that.
|
||||
let length;
|
||||
if (ObjectPrototypeIsPrototypeOf(DataViewPrototype, view)) {
|
||||
length = value.byteLength;
|
||||
} else {
|
||||
length = value.length;
|
||||
const tag = TypedArrayPrototypeGetSymbolToStringTag(value);
|
||||
// DataView
|
||||
if (tag === undefined) {
|
||||
return new DataView(
|
||||
structuredClone(DataViewPrototypeGetBuffer(value)),
|
||||
DataViewPrototypeGetByteOffset(value),
|
||||
DataViewPrototypeGetByteLength(value),
|
||||
);
|
||||
}
|
||||
return new (value.constructor)(
|
||||
clonedBuffer,
|
||||
value.byteOffset,
|
||||
length,
|
||||
// TypedArray
|
||||
let Constructor;
|
||||
switch (tag) {
|
||||
case "Int8Array":
|
||||
Constructor = Int8Array;
|
||||
break;
|
||||
case "Int16Array":
|
||||
Constructor = Int16Array;
|
||||
break;
|
||||
case "Int32Array":
|
||||
Constructor = Int32Array;
|
||||
break;
|
||||
case "BigInt64Array":
|
||||
Constructor = BigInt64Array;
|
||||
break;
|
||||
case "Uint8Array":
|
||||
Constructor = Uint8Array;
|
||||
break;
|
||||
case "Uint8ClampedArray":
|
||||
Constructor = Uint8ClampedArray;
|
||||
break;
|
||||
case "Uint16Array":
|
||||
Constructor = Uint16Array;
|
||||
break;
|
||||
case "Uint32Array":
|
||||
Constructor = Uint32Array;
|
||||
break;
|
||||
case "BigUint64Array":
|
||||
Constructor = BigUint64Array;
|
||||
break;
|
||||
case "Float32Array":
|
||||
Constructor = Float32Array;
|
||||
break;
|
||||
case "Float64Array":
|
||||
Constructor = Float64Array;
|
||||
break;
|
||||
}
|
||||
return new Constructor(
|
||||
structuredClone(TypedArrayPrototypeGetBuffer(value)),
|
||||
TypedArrayPrototypeGetByteOffset(value),
|
||||
TypedArrayPrototypeGetLength(value),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue