@@ -57,6 +57,7 @@ using v8::ArrayBufferView;
5757using v8::BackingStore;
5858using v8::Context;
5959using v8::EscapableHandleScope;
60+ using v8::FastApiTypedArray;
6061using v8::FunctionCallbackInfo;
6162using v8::Global;
6263using v8::HandleScope;
@@ -1071,37 +1072,57 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
10711072 result == haystack_length ? -1 : static_cast <int >(result));
10721073}
10731074
1074- void IndexOfNumber (const FunctionCallbackInfo<Value>& args) {
1075+ int32_t IndexOfNumber (const uint8_t * buffer_data,
1076+ size_t buffer_length,
1077+ uint32_t needle,
1078+ int64_t offset_i64,
1079+ bool is_forward) {
1080+ int64_t opt_offset = IndexOfOffset (buffer_length, offset_i64, 1 , is_forward);
1081+ if (opt_offset <= -1 || buffer_length == 0 ) {
1082+ return -1 ;
1083+ }
1084+ size_t offset = static_cast <size_t >(opt_offset);
1085+ CHECK_LT (offset, buffer_length);
1086+
1087+ const void * ptr;
1088+ if (is_forward) {
1089+ ptr = memchr (buffer_data + offset, needle, buffer_length - offset);
1090+ } else {
1091+ ptr = node::stringsearch::MemrchrFill (buffer_data, needle, offset + 1 );
1092+ }
1093+ const uint8_t * ptr_uint8 = static_cast <const uint8_t *>(ptr);
1094+ return ptr != nullptr ? static_cast <int32_t >(ptr_uint8 - buffer_data) : -1 ;
1095+ }
1096+
1097+ void SlowIndexOfNumber (const FunctionCallbackInfo<Value>& args) {
10751098 CHECK (args[1 ]->IsUint32 ());
10761099 CHECK (args[2 ]->IsNumber ());
10771100 CHECK (args[3 ]->IsBoolean ());
10781101
10791102 THROW_AND_RETURN_UNLESS_BUFFER (Environment::GetCurrent (args), args[0 ]);
1080- ArrayBufferViewContents<char > buffer (args[0 ]);
1103+ ArrayBufferViewContents<uint8_t > buffer (args[0 ]);
10811104
10821105 uint32_t needle = args[1 ].As <Uint32>()->Value ();
10831106 int64_t offset_i64 = args[2 ].As <Integer>()->Value ();
10841107 bool is_forward = args[3 ]->IsTrue ();
10851108
1086- int64_t opt_offset =
1087- IndexOfOffset (buffer.length (), offset_i64, 1 , is_forward);
1088- if (opt_offset <= -1 || buffer.length () == 0 ) {
1089- return args.GetReturnValue ().Set (-1 );
1090- }
1091- size_t offset = static_cast <size_t >(opt_offset);
1092- CHECK_LT (offset, buffer.length ());
1109+ args.GetReturnValue ().Set (IndexOfNumber (
1110+ buffer.data (), buffer.length (), needle, offset_i64, is_forward));
1111+ }
10931112
1094- const void * ptr;
1095- if (is_forward) {
1096- ptr = memchr (buffer. data () + offset, needle, buffer. length () - offset);
1097- } else {
1098- ptr = node::stringsearch::MemrchrFill (buffer. data (), needle, offset + 1 );
1099- }
1100- const char * ptr_char = static_cast < const char *>(ptr );
1101- args. GetReturnValue (). Set (ptr ? static_cast < int >(ptr_char - buffer. data ())
1102- : - 1 );
1113+ int32_t FastIndexOfNumber (v8::Local<v8::Value>,
1114+ const FastApiTypedArray< uint8_t >& buffer,
1115+ uint32_t needle,
1116+ int64_t offset_i64,
1117+ bool is_forward) {
1118+ uint8_t * buffer_data;
1119+ CHECK (buffer. getStorageIfAligned (&buffer_data) );
1120+ return IndexOfNumber (
1121+ buffer_data, buffer. length (), needle, offset_i64, is_forward );
11031122}
11041123
1124+ static v8::CFunction fast_index_of_number (
1125+ v8::CFunction::Make (FastIndexOfNumber));
11051126
11061127void Swap16 (const FunctionCallbackInfo<Value>& args) {
11071128 Environment* env = Environment::GetCurrent (args);
@@ -1413,7 +1434,11 @@ void Initialize(Local<Object> target,
14131434 SetMethodNoSideEffect (context, target, " compareOffset" , CompareOffset);
14141435 SetMethod (context, target, " fill" , Fill);
14151436 SetMethodNoSideEffect (context, target, " indexOfBuffer" , IndexOfBuffer);
1416- SetMethodNoSideEffect (context, target, " indexOfNumber" , IndexOfNumber);
1437+ SetFastMethodNoSideEffect (context,
1438+ target,
1439+ " indexOfNumber" ,
1440+ SlowIndexOfNumber,
1441+ &fast_index_of_number);
14171442 SetMethodNoSideEffect (context, target, " indexOfString" , IndexOfString);
14181443
14191444 SetMethod (context, target, " detachArrayBuffer" , DetachArrayBuffer);
@@ -1472,7 +1497,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
14721497 registry->Register (CompareOffset);
14731498 registry->Register (Fill);
14741499 registry->Register (IndexOfBuffer);
1475- registry->Register (IndexOfNumber);
1500+ registry->Register (SlowIndexOfNumber);
1501+ registry->Register (FastIndexOfNumber);
1502+ registry->Register (fast_index_of_number.GetTypeInfo ());
14761503 registry->Register (IndexOfString);
14771504
14781505 registry->Register (Swap16);
0 commit comments