@@ -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-
16791668void 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