summaryrefslogtreecommitdiff
path: root/ext/web/02_structured_clone.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/web/02_structured_clone.js')
-rw-r--r--ext/web/02_structured_clone.js94
1 files changed, 75 insertions, 19 deletions
diff --git a/ext/web/02_structured_clone.js b/ext/web/02_structured_clone.js
index f8a88a7ef..793cb1c75 100644
--- a/ext/web/02_structured_clone.js
+++ b/ext/web/02_structured_clone.js
@@ -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),
+ );
+ }
+ // 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 (value.constructor)(
- clonedBuffer,
- value.byteOffset,
- length,
+ return new Constructor(
+ structuredClone(TypedArrayPrototypeGetBuffer(value)),
+ TypedArrayPrototypeGetByteOffset(value),
+ TypedArrayPrototypeGetLength(value),
);
}