@@ -576,44 +576,40 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
576
576
args.GetReturnValue ().Set (ret);
577
577
}
578
578
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) {
581
581
Environment* env = Environment::GetCurrent (args);
582
582
583
- THROW_AND_RETURN_UNLESS_BUFFER (env, args[0 ]);
584
- THROW_AND_RETURN_UNLESS_BUFFER (env, args[1 ]);
585
583
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);
588
585
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 ();
597
589
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
+ }
601
593
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));
605
603
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)) ;
608
606
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);
612
608
613
- memmove (target_data + target_start, source.data () + source_start, to_copy);
614
- args.GetReturnValue ().Set (to_copy);
609
+ return to_copy;
615
610
}
616
611
612
+ static v8::CFunction fast_copy (v8::CFunction::Make(FastCopy));
617
613
618
614
void Fill (const FunctionCallbackInfo<Value>& args) {
619
615
Environment* env = Environment::GetCurrent (args);
@@ -1447,7 +1443,7 @@ void Initialize(Local<Object> target,
1447
1443
" byteLengthUtf8" ,
1448
1444
SlowByteLengthUtf8,
1449
1445
&fast_byte_length_utf8);
1450
- SetMethod (context, target, " copy" , Copy );
1446
+ SetFastMethod (context, target, " copy" , SlowCopy, &fast_copy );
1451
1447
SetFastMethodNoSideEffect (context, target, " compare" , Compare, &fast_compare);
1452
1448
SetMethodNoSideEffect (context, target, " compareOffset" , CompareOffset);
1453
1449
SetMethod (context, target, " fill" , Fill);
@@ -1510,7 +1506,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
1510
1506
registry->Register (SlowByteLengthUtf8);
1511
1507
registry->Register (fast_byte_length_utf8.GetTypeInfo ());
1512
1508
registry->Register (FastByteLengthUtf8);
1513
- registry->Register (Copy);
1509
+ registry->Register (SlowCopy);
1510
+ registry->Register (fast_copy.GetTypeInfo ());
1511
+ registry->Register (FastCopy);
1514
1512
registry->Register (Compare);
1515
1513
registry->Register (FastCompare);
1516
1514
registry->Register (fast_compare.GetTypeInfo ());
0 commit comments