@@ -569,7 +569,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
569569}
570570
571571//  bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
572- void  Copy (const  FunctionCallbackInfo<Value> &args) {
572+ void  SlowCopy (const  FunctionCallbackInfo<Value> &args) {
573573  Environment* env = Environment::GetCurrent (args);
574574
575575  THROW_AND_RETURN_UNLESS_BUFFER (env, args[0 ]);
@@ -606,6 +606,40 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
606606  args.GetReturnValue ().Set (to_copy);
607607}
608608
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));
609643
610644void  Fill (const  FunctionCallbackInfo<Value>& args) {
611645  Environment* env = Environment::GetCurrent (args);
@@ -1275,7 +1309,7 @@ void Initialize(Local<Object> target,
12751309                            " byteLengthUtf8" 
12761310                            SlowByteLengthUtf8,
12771311                            &fast_byte_length_utf8);
1278-   SetMethod (context, target, " copy" Copy );
1312+   SetFastMethod (context, target, " copy" SlowCopy, &fast_copy );
12791313  SetMethodNoSideEffect (context, target, " compare" 
12801314  SetMethodNoSideEffect (context, target, " compareOffset" 
12811315  SetMethod (context, target, " fill" 
@@ -1334,7 +1368,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
13341368  registry->Register (SlowByteLengthUtf8);
13351369  registry->Register (fast_byte_length_utf8.GetTypeInfo ());
13361370  registry->Register (FastByteLengthUtf8);
1337-   registry->Register (Copy);
1371+   registry->Register (SlowCopy);
1372+   registry->Register (fast_copy.GetTypeInfo ());
1373+   registry->Register (FastCopy);
13381374  registry->Register (Compare);
13391375  registry->Register (CompareOffset);
13401376  registry->Register (Fill);
0 commit comments