@@ -576,44 +576,40 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
576576 args.GetReturnValue ().Set (ret);
577577}
578578
579- // bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
580- void Copy (const FunctionCallbackInfo<Value> & args) {
579+ // Assume caller has properly validated args.
580+ void SlowCopy (const FunctionCallbackInfo<Value>& args) {
581581 Environment* env = Environment::GetCurrent (args);
582582
583- THROW_AND_RETURN_UNLESS_BUFFER (env, args[0 ]);
584- THROW_AND_RETURN_UNLESS_BUFFER (env, args[1 ]);
585583 ArrayBufferViewContents<char > source (args[0 ]);
586- Local<Object> target_obj = args[1 ].As <Object>();
587- SPREAD_BUFFER_ARG (target_obj, target);
584+ SPREAD_BUFFER_ARG (args[1 ].As <Object>(), target);
588585
589- size_t target_start = 0 ;
590- size_t source_start = 0 ;
591- size_t source_end = 0 ;
592-
593- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], 0 , &target_start));
594- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[3 ], 0 , &source_start));
595- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[4 ], source.length (),
596- &source_end));
586+ const auto target_start = args[2 ]->Uint32Value (env->context ()).ToChecked ();
587+ const auto source_start = args[3 ]->Uint32Value (env->context ()).ToChecked ();
588+ const auto to_copy = args[4 ]->Uint32Value (env->context ()).ToChecked ();
597589
598- // Copy 0 bytes; we're done
599- if (target_start >= target_length || source_start >= source_end)
600- return args. GetReturnValue (). Set ( 0 );
590+ memmove (target_data + target_start, source. data () + source_start, to_copy);
591+ args. GetReturnValue (). Set (to_copy);
592+ }
601593
602- if (source_start > source.length ())
603- return THROW_ERR_OUT_OF_RANGE (
604- env, " The value of \" sourceStart\" is out of range." );
594+ // Assume caller has properly validated args.
595+ uint32_t FastCopy (Local<Value> receiver,
596+ const v8::FastApiTypedArray<uint8_t >& source,
597+ const v8::FastApiTypedArray<uint8_t >& target,
598+ uint32_t target_start,
599+ uint32_t source_start,
600+ uint32_t to_copy) {
601+ uint8_t * source_data;
602+ CHECK (source.getStorageIfAligned (&source_data));
605603
606- if (source_end - source_start > target_length - target_start)
607- source_end = source_start + target_length - target_start ;
604+ uint8_t * target_data;
605+ CHECK (target. getStorageIfAligned (&target_data)) ;
608606
609- uint32_t to_copy = std::min (
610- std::min (source_end - source_start, target_length - target_start),
611- source.length () - source_start);
607+ memmove (target_data + target_start, source_data + source_start, to_copy);
612608
613- memmove (target_data + target_start, source.data () + source_start, to_copy);
614- args.GetReturnValue ().Set (to_copy);
609+ return to_copy;
615610}
616611
612+ static v8::CFunction fast_copy (v8::CFunction::Make(FastCopy));
617613
618614void Fill (const FunctionCallbackInfo<Value>& args) {
619615 Environment* env = Environment::GetCurrent (args);
@@ -1447,7 +1443,7 @@ void Initialize(Local<Object> target,
14471443 " byteLengthUtf8" ,
14481444 SlowByteLengthUtf8,
14491445 &fast_byte_length_utf8);
1450- SetMethod (context, target, " copy" , Copy );
1446+ SetFastMethod (context, target, " copy" , SlowCopy, &fast_copy );
14511447 SetFastMethodNoSideEffect (context, target, " compare" , Compare, &fast_compare);
14521448 SetMethodNoSideEffect (context, target, " compareOffset" , CompareOffset);
14531449 SetMethod (context, target, " fill" , Fill);
@@ -1510,7 +1506,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
15101506 registry->Register (SlowByteLengthUtf8);
15111507 registry->Register (fast_byte_length_utf8.GetTypeInfo ());
15121508 registry->Register (FastByteLengthUtf8);
1513- registry->Register (Copy);
1509+ registry->Register (SlowCopy);
1510+ registry->Register (fast_copy.GetTypeInfo ());
1511+ registry->Register (FastCopy);
15141512 registry->Register (Compare);
15151513 registry->Register (FastCompare);
15161514 registry->Register (fast_compare.GetTypeInfo ());
0 commit comments