Skip to content

Commit 6b117f7

Browse files
committed
src: use native CopyArrayBufferBytes for webstream buffer copy
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
1 parent f71d644 commit 6b117f7

1 file changed

Lines changed: 37 additions & 43 deletions

File tree

‎src/node_buffer.cc‎

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,65 +1655,54 @@ static void SetDetachKey(const FunctionCallbackInfo<Value>& args) {
16551655
ab->SetDetachKey(key);
16561656
}
16571657

1658-
namespace {
1659-
1660-
std::pair<void*, size_t> DecomposeBufferToParts(Local<Value> buffer) {
1661-
void* pointer;
1662-
size_t byte_length;
1663-
if (buffer->IsArrayBuffer()) {
1664-
Local<ArrayBuffer> ab = buffer.As<ArrayBuffer>();
1665-
pointer = ab->Data();
1666-
byte_length = ab->ByteLength();
1667-
} else if (buffer->IsSharedArrayBuffer()) {
1668-
Local<SharedArrayBuffer> ab = buffer.As<SharedArrayBuffer>();
1669-
pointer = ab->Data();
1670-
byte_length = ab->ByteLength();
1671-
} else {
1672-
UNREACHABLE(); // Caller must validate.
1673-
}
1674-
return {pointer, byte_length};
1658+
void CopyArrayBufferImpl(Local<ArrayBuffer> target,
1659+
uint32_t target_start,
1660+
Local<ArrayBuffer> source,
1661+
uint32_t source_start,
1662+
uint32_t bytes_to_copy) {
1663+
uint32_t bytes_copied = source->CopyArrayBufferBytes(
1664+
source_start, bytes_to_copy, target, target_start);
1665+
CHECK_EQ(bytes_copied, bytes_to_copy);
16751666
}
16761667

1677-
} // namespace
1678-
16791668
void CopyArrayBuffer(const FunctionCallbackInfo<Value>& args) {
16801669
// args[0] == Destination ArrayBuffer
16811670
// args[1] == Destination ArrayBuffer Offset
16821671
// args[2] == Source ArrayBuffer
16831672
// args[3] == Source ArrayBuffer Offset
16841673
// args[4] == bytesToCopy
16851674

1686-
CHECK(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
1675+
CHECK(args[0]->IsArrayBuffer());
16871676
CHECK(args[1]->IsUint32());
1688-
CHECK(args[2]->IsArrayBuffer() || args[2]->IsSharedArrayBuffer());
1677+
CHECK(args[2]->IsArrayBuffer());
16891678
CHECK(args[3]->IsUint32());
16901679
CHECK(args[4]->IsUint32());
16911680

1692-
void* destination;
1693-
size_t destination_byte_length;
1694-
std::tie(destination, destination_byte_length) =
1695-
DecomposeBufferToParts(args[0]);
1696-
1697-
void* source;
1698-
size_t source_byte_length;
1699-
std::tie(source, source_byte_length) = DecomposeBufferToParts(args[2]);
1700-
1701-
uint32_t destination_offset = args[1].As<Uint32>()->Value();
1702-
uint32_t source_offset = args[3].As<Uint32>()->Value();
1703-
size_t bytes_to_copy = args[4].As<Uint32>()->Value();
1681+
CopyArrayBufferImpl(args[0].As<ArrayBuffer>(),
1682+
args[1].As<Uint32>()->Value(),
1683+
args[2].As<ArrayBuffer>(),
1684+
args[3].As<Uint32>()->Value(),
1685+
args[4].As<Uint32>()->Value());
1686+
}
17041687

1705-
// Assert the offsets are within bounds before the subtractions below, which
1706-
// would otherwise underflow and defeat the bytes_to_copy bounds checks.
1707-
CHECK_LE(destination_offset, destination_byte_length);
1708-
CHECK_LE(source_offset, source_byte_length);
1709-
CHECK_GE(destination_byte_length - destination_offset, bytes_to_copy);
1710-
CHECK_GE(source_byte_length - source_offset, bytes_to_copy);
1688+
void FastCopyArrayBuffer(Local<Value> receiver,
1689+
Local<Value> target,
1690+
uint32_t target_start,
1691+
Local<Value> source,
1692+
uint32_t source_start,
1693+
uint32_t bytes_to_copy) {
1694+
CHECK(target->IsArrayBuffer());
1695+
CHECK(source->IsArrayBuffer());
17111696

1712-
uint8_t* dest = static_cast<uint8_t*>(destination) + destination_offset;
1713-
uint8_t* src = static_cast<uint8_t*>(source) + source_offset;
1714-
memcpy(dest, src, bytes_to_copy);
1697+
CopyArrayBufferImpl(target.As<ArrayBuffer>(),
1698+
target_start,
1699+
source.As<ArrayBuffer>(),
1700+
source_start,
1701+
bytes_to_copy);
17151702
}
17161703

1704+
static CFunction fast_copy_array_buffer(CFunction::Make(FastCopyArrayBuffer));
1705+
17171706
// Converts a number parameter to size_t suitable for ArrayBuffer sizes
17181707
// Could be larger than uint32_t
17191708
// See v8::internal::TryNumberToSize and v8::internal::NumberToSize
@@ -1937,7 +1926,11 @@ void Initialize(Local<Object> target,
19371926
&fast_index_of_number);
19381927
SetMethodNoSideEffect(context, target, "indexOfString", IndexOfString);
19391928

1940-
SetMethod(context, target, "copyArrayBuffer", CopyArrayBuffer);
1929+
SetFastMethod(context,
1930+
target,
1931+
"copyArrayBuffer",
1932+
CopyArrayBuffer,
1933+
&fast_copy_array_buffer);
19411934
SetMethodNoSideEffect(
19421935
context, target, "createUnsafeArrayBuffer", CreateUnsafeArrayBuffer);
19431936
SetMethodNoSideEffect(
@@ -2060,6 +2053,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
20602053
registry->Register(StringWrite<UTF8>);
20612054

20622055
registry->Register(CopyArrayBuffer);
2056+
registry->Register(fast_copy_array_buffer);
20632057
registry->Register(CreateUnsafeArrayBuffer);
20642058
registry->Register(ArrayBufferAlignedOffset);
20652059

0 commit comments

Comments
 (0)