@@ -569,7 +569,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
569
569
}
570
570
571
571
// bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
572
- void Copy (const FunctionCallbackInfo<Value> &args) {
572
+ void SlowCopy (const FunctionCallbackInfo<Value> &args) {
573
573
Environment* env = Environment::GetCurrent (args);
574
574
575
575
THROW_AND_RETURN_UNLESS_BUFFER (env, args[0 ]);
@@ -606,6 +606,40 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
606
606
args.GetReturnValue ().Set (to_copy);
607
607
}
608
608
609
+ uint32_t FastCopy (Local<Value> receiver,
610
+ Local<Value> source_obj,
611
+ Local<Value> target_obj,
612
+ uint32_t target_start,
613
+ uint32_t source_start,
614
+ uint32_t source_end) {
615
+ ArrayBufferViewContents<char > source (source_obj);
616
+
617
+ SPREAD_BUFFER_ARG (target_obj, target);
618
+
619
+ // Copy 0 bytes; we're done
620
+ if (target_start >= target_length || source_start >= source_end)
621
+ return 0 ;
622
+
623
+ if (source_start > source.length ()) {
624
+ // TODO (fix): V8 12.8 allows throwing in fast call.
625
+ assert (false );
626
+ return 0 ;
627
+ }
628
+
629
+ if (source_end - source_start > target_length - target_start)
630
+ source_end = source_start + target_length - target_start;
631
+
632
+ uint32_t to_copy = std::min<size_t >(
633
+ std::min<size_t >(source_end - source_start, target_length - target_start),
634
+ source.length () - source_start);
635
+
636
+ memmove (target_data + target_start, source.data () + source_start, to_copy);
637
+
638
+ return to_copy;
639
+ }
640
+
641
+ static v8::CFunction fast_copy (
642
+ v8::CFunction::Make (FastCopy));
609
643
610
644
void Fill (const FunctionCallbackInfo<Value>& args) {
611
645
Environment* env = Environment::GetCurrent (args);
@@ -1275,7 +1309,7 @@ void Initialize(Local<Object> target,
1275
1309
" byteLengthUtf8" ,
1276
1310
SlowByteLengthUtf8,
1277
1311
&fast_byte_length_utf8);
1278
- SetMethod (context, target, " copy" , Copy );
1312
+ SetFastMethod (context, target, " copy" , SlowCopy, &fast_copy );
1279
1313
SetMethodNoSideEffect (context, target, " compare" , Compare);
1280
1314
SetMethodNoSideEffect (context, target, " compareOffset" , CompareOffset);
1281
1315
SetMethod (context, target, " fill" , Fill);
@@ -1334,7 +1368,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
1334
1368
registry->Register (SlowByteLengthUtf8);
1335
1369
registry->Register (fast_byte_length_utf8.GetTypeInfo ());
1336
1370
registry->Register (FastByteLengthUtf8);
1337
- registry->Register (Copy);
1371
+ registry->Register (SlowCopy);
1372
+ registry->Register (fast_copy.GetTypeInfo ());
1373
+ registry->Register (FastCopy);
1338
1374
registry->Register (Compare);
1339
1375
registry->Register (CompareOffset);
1340
1376
registry->Register (Fill);
0 commit comments