From f6835b9f1a04259766c766a46cf37718640cedab Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sat, 15 Feb 2025 13:24:36 -0500 Subject: [PATCH] Normative: Fix ArrayBufferCopyAndDetach Ref #31 * Always respect [[ArrayBufferDetachKey]]. * Always detach. --- spec.emu | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/spec.emu b/spec.emu index 04c6602..f3ef762 100644 --- a/spec.emu +++ b/spec.emu @@ -454,20 +454,22 @@ contributors: Mark S. Miller, Richard Gibson 1. Let _newByteLength_ be ? ToIndex(_newLength_). 1. If IsDetachedBuffer(_arrayBuffer_) is *true*, throw a *TypeError* exception. 1. If IsImmutableBuffer(_arrayBuffer_) is *true*, throw a *TypeError* exception. + 1. If _arrayBuffer_.[[ArrayBufferDetachKey]] is not *undefined*, throw a *TypeError* exception. 1. Let _copyLength_ be min(_newByteLength_, _arrayBuffer_.[[ArrayBufferByteLength]]). 1. If _preserveResizability_ is ~immutable~, then - 1. Return ? AllocateImmutableArrayBuffer(%ArrayBuffer%, _newByteLength_, _arrayBuffer_.[[ArrayBufferData]], 0, _copyLength_). - 1. If _preserveResizability_ is ~preserve-resizability~ and IsFixedLengthArrayBuffer(_arrayBuffer_) is *false*, then - 1. Let _newMaxByteLength_ be _arrayBuffer_.[[ArrayBufferMaxByteLength]]. - 1. Else, - 1. Let _newMaxByteLength_ be ~empty~. - 1. If _arrayBuffer_.[[ArrayBufferDetachKey]] is not *undefined*, throw a *TypeError* exception. - 1. Let _newBuffer_ be ? AllocateArrayBuffer(%ArrayBuffer%, _newByteLength_, _newMaxByteLength_). - 1. Let _copyLength_ be min(_newByteLength_, _arrayBuffer_.[[ArrayBufferByteLength]]). - 1. Let _fromBlock_ be _arrayBuffer_.[[ArrayBufferData]]. - 1. Let _toBlock_ be _newBuffer_.[[ArrayBufferData]]. - 1. Perform CopyDataBlockBytes(_toBlock_, 0, _fromBlock_, 0, _copyLength_). - 1. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as a zero-copy move or a `realloc`. + 1. Let _newBuffer_ be ? AllocateImmutableArrayBuffer(%ArrayBuffer%, _newByteLength_, _arrayBuffer_.[[ArrayBufferData]], 0, _copyLength_). + 1. Else, + 1. If _preserveResizability_ is ~preserve-resizability~ and IsFixedLengthArrayBuffer(_arrayBuffer_) is *false*, then + 1. Let _newMaxByteLength_ be _arrayBuffer_.[[ArrayBufferMaxByteLength]]. + 1. Else, + 1. Let _newMaxByteLength_ be ~empty~. + 1. If _arrayBuffer_.[[ArrayBufferDetachKey]] is not *undefined*, throw a *TypeError* exception. + 1. Let _newBuffer_ be ? AllocateArrayBuffer(%ArrayBuffer%, _newByteLength_, _newMaxByteLength_). + 1. Let _copyLength_ be min(_newByteLength_, _arrayBuffer_.[[ArrayBufferByteLength]]). + 1. Let _fromBlock_ be _arrayBuffer_.[[ArrayBufferData]]. + 1. Let _toBlock_ be _newBuffer_.[[ArrayBufferData]]. + 1. Perform CopyDataBlockBytes(_toBlock_, 0, _fromBlock_, 0, _copyLength_). + 1. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as a zero-copy move or a `realloc`. 1. Perform ! DetachArrayBuffer(_arrayBuffer_). 1. Return _newBuffer_.