Skip to content

Commit 1a179e1

Browse files
addaleaxtargos
authored andcommitted
src: use ArrayBufferViewContents more frequently
Using `ArrayBufferViewContents` over `Buffer::Data()`/`Buffer::Length()` or `SPREAD_BUFFER_ARG` has the advantages of creating fewer individual variables to keep track off, not being a “magic” macro that creates variables, reducing code size, and being faster when receiving on-heap TypedArrays. PR-URL: #27920 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent b9cc407 commit 1a179e1

9 files changed

+77
-81
lines changed

src/js_stream.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
167167
JSStream* wrap;
168168
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
169169

170-
CHECK(Buffer::HasInstance(args[0]));
171-
char* data = Buffer::Data(args[0]);
172-
int len = Buffer::Length(args[0]);
170+
ArrayBufferViewContents<char> buffer(args[0]);
171+
const char* data = buffer.data();
172+
int len = buffer.length();
173173

174174
// Repeatedly ask the stream's owner for memory, copy the data that we
175175
// just read from JS into those buffers and emit them as reads.

src/node_buffer.cc

+40-40
Original file line numberDiff line numberDiff line change
@@ -463,17 +463,17 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
463463
Isolate* isolate = env->isolate();
464464

465465
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
466-
SPREAD_BUFFER_ARG(args.This(), ts_obj);
466+
ArrayBufferViewContents<char> buffer(args.This());
467467

468-
if (ts_obj_length == 0)
468+
if (buffer.length() == 0)
469469
return args.GetReturnValue().SetEmptyString();
470470

471-
SLICE_START_END(env, args[0], args[1], ts_obj_length)
471+
SLICE_START_END(env, args[0], args[1], buffer.length())
472472

473473
Local<Value> error;
474474
MaybeLocal<Value> ret =
475475
StringBytes::Encode(isolate,
476-
ts_obj_data + start,
476+
buffer.data() + start,
477477
length,
478478
encoding,
479479
&error);
@@ -492,9 +492,8 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
492492

493493
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
494494
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
495-
Local<Object> buffer_obj = args[0].As<Object>();
495+
ArrayBufferViewContents<char> source(args[0]);
496496
Local<Object> target_obj = args[1].As<Object>();
497-
SPREAD_BUFFER_ARG(buffer_obj, ts_obj);
498497
SPREAD_BUFFER_ARG(target_obj, target);
499498

500499
size_t target_start = 0;
@@ -503,14 +502,14 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
503502

504503
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &target_start));
505504
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[3], 0, &source_start));
506-
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[4], ts_obj_length,
505+
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[4], source.length(),
507506
&source_end));
508507

509508
// Copy 0 bytes; we're done
510509
if (target_start >= target_length || source_start >= source_end)
511510
return args.GetReturnValue().Set(0);
512511

513-
if (source_start > ts_obj_length)
512+
if (source_start > source.length())
514513
return THROW_ERR_OUT_OF_RANGE(
515514
env, "The value of \"sourceStart\" is out of range.");
516515

@@ -519,9 +518,9 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
519518

520519
uint32_t to_copy = std::min(
521520
std::min(source_end - source_start, target_length - target_start),
522-
ts_obj_length - source_start);
521+
source.length() - source_start);
523522

524-
memmove(target_data + target_start, ts_obj_data + source_start, to_copy);
523+
memmove(target_data + target_start, source.data() + source_start, to_copy);
525524
args.GetReturnValue().Set(to_copy);
526525
}
527526

@@ -689,8 +688,8 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
689688

690689
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
691690
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
692-
SPREAD_BUFFER_ARG(args[0], ts_obj);
693-
SPREAD_BUFFER_ARG(args[1], target);
691+
ArrayBufferViewContents<char> source(args[0]);
692+
ArrayBufferViewContents<char> target(args[1]);
694693

695694
size_t target_start = 0;
696695
size_t source_start = 0;
@@ -699,15 +698,15 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
699698

700699
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &target_start));
701700
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[3], 0, &source_start));
702-
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[4], target_length,
701+
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[4], target.length(),
703702
&target_end));
704-
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[5], ts_obj_length,
703+
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[5], source.length(),
705704
&source_end));
706705

707-
if (source_start > ts_obj_length)
706+
if (source_start > source.length())
708707
return THROW_ERR_OUT_OF_RANGE(
709708
env, "The value of \"sourceStart\" is out of range.");
710-
if (target_start > target_length)
709+
if (target_start > target.length())
711710
return THROW_ERR_OUT_OF_RANGE(
712711
env, "The value of \"targetStart\" is out of range.");
713712

@@ -716,11 +715,11 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
716715

717716
size_t to_cmp =
718717
std::min(std::min(source_end - source_start, target_end - target_start),
719-
ts_obj_length - source_start);
718+
source.length() - source_start);
720719

721720
int val = normalizeCompareVal(to_cmp > 0 ?
722-
memcmp(ts_obj_data + source_start,
723-
target_data + target_start,
721+
memcmp(source.data() + source_start,
722+
target.data() + target_start,
724723
to_cmp) : 0,
725724
source_end - source_start,
726725
target_end - target_start);
@@ -733,14 +732,14 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
733732

734733
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
735734
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
736-
SPREAD_BUFFER_ARG(args[0], obj_a);
737-
SPREAD_BUFFER_ARG(args[1], obj_b);
735+
ArrayBufferViewContents<char> a(args[0]);
736+
ArrayBufferViewContents<char> b(args[1]);
738737

739-
size_t cmp_length = std::min(obj_a_length, obj_b_length);
738+
size_t cmp_length = std::min(a.length(), b.length());
740739

741740
int val = normalizeCompareVal(cmp_length > 0 ?
742-
memcmp(obj_a_data, obj_b_data, cmp_length) : 0,
743-
obj_a_length, obj_b_length);
741+
memcmp(a.data(), b.data(), cmp_length) : 0,
742+
a.length(), b.length());
744743
args.GetReturnValue().Set(val);
745744
}
746745

@@ -792,16 +791,16 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
792791
enum encoding enc = ParseEncoding(isolate, args[3], UTF8);
793792

794793
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
795-
SPREAD_BUFFER_ARG(args[0], ts_obj);
794+
ArrayBufferViewContents<char> buffer(args[0]);
796795

797796
Local<String> needle = args[1].As<String>();
798797
int64_t offset_i64 = args[2].As<Integer>()->Value();
799798
bool is_forward = args[4]->IsTrue();
800799

801-
const char* haystack = ts_obj_data;
800+
const char* haystack = buffer.data();
802801
// Round down to the nearest multiple of 2 in case of UCS2.
803802
const size_t haystack_length = (enc == UCS2) ?
804-
ts_obj_length &~ 1 : ts_obj_length; // NOLINT(whitespace/operators)
803+
buffer.length() &~ 1 : buffer.length(); // NOLINT(whitespace/operators)
805804

806805
size_t needle_length;
807806
if (!StringBytes::Size(isolate, needle, enc).To(&needle_length)) return;
@@ -909,15 +908,15 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
909908

910909
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
911910
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[1]);
912-
SPREAD_BUFFER_ARG(args[0], ts_obj);
913-
SPREAD_BUFFER_ARG(args[1], buf);
911+
ArrayBufferViewContents<char> haystack_contents(args[0]);
912+
ArrayBufferViewContents<char> needle_contents(args[1]);
914913
int64_t offset_i64 = args[2].As<Integer>()->Value();
915914
bool is_forward = args[4]->IsTrue();
916915

917-
const char* haystack = ts_obj_data;
918-
const size_t haystack_length = ts_obj_length;
919-
const char* needle = buf_data;
920-
const size_t needle_length = buf_length;
916+
const char* haystack = haystack_contents.data();
917+
const size_t haystack_length = haystack_contents.length();
918+
const char* needle = needle_contents.data();
919+
const size_t needle_length = needle_contents.length();
921920

922921
int64_t opt_offset = IndexOfOffset(haystack_length,
923922
offset_i64,
@@ -978,27 +977,28 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
978977
CHECK(args[3]->IsBoolean());
979978

980979
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
981-
SPREAD_BUFFER_ARG(args[0], ts_obj);
980+
ArrayBufferViewContents<char> buffer(args[0]);
982981

983982
uint32_t needle = args[1].As<Uint32>()->Value();
984983
int64_t offset_i64 = args[2].As<Integer>()->Value();
985984
bool is_forward = args[3]->IsTrue();
986985

987-
int64_t opt_offset = IndexOfOffset(ts_obj_length, offset_i64, 1, is_forward);
988-
if (opt_offset <= -1 || ts_obj_length == 0) {
986+
int64_t opt_offset =
987+
IndexOfOffset(buffer.length(), offset_i64, 1, is_forward);
988+
if (opt_offset <= -1 || buffer.length() == 0) {
989989
return args.GetReturnValue().Set(-1);
990990
}
991991
size_t offset = static_cast<size_t>(opt_offset);
992-
CHECK_LT(offset, ts_obj_length);
992+
CHECK_LT(offset, buffer.length());
993993

994994
const void* ptr;
995995
if (is_forward) {
996-
ptr = memchr(ts_obj_data + offset, needle, ts_obj_length - offset);
996+
ptr = memchr(buffer.data() + offset, needle, buffer.length() - offset);
997997
} else {
998-
ptr = node::stringsearch::MemrchrFill(ts_obj_data, needle, offset + 1);
998+
ptr = node::stringsearch::MemrchrFill(buffer.data(), needle, offset + 1);
999999
}
10001000
const char* ptr_char = static_cast<const char*>(ptr);
1001-
args.GetReturnValue().Set(ptr ? static_cast<int>(ptr_char - ts_obj_data)
1001+
args.GetReturnValue().Set(ptr ? static_cast<int>(ptr_char - buffer.data())
10021002
: -1);
10031003
}
10041004

src/node_crypto.cc

+10-17
Original file line numberDiff line numberDiff line change
@@ -5766,11 +5766,10 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
57665766
ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
57675767

57685768
THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Private key");
5769+
ArrayBufferViewContents<unsigned char> priv_buffer(args[0]);
57695770

57705771
BignumPointer priv(BN_bin2bn(
5771-
reinterpret_cast<unsigned char*>(Buffer::Data(args[0].As<Object>())),
5772-
Buffer::Length(args[0].As<Object>()),
5773-
nullptr));
5772+
priv_buffer.data(), priv_buffer.length(), nullptr));
57745773
if (!priv)
57755774
return env->ThrowError("Failed to convert Buffer to BN");
57765775

@@ -6687,14 +6686,11 @@ OpenSSLBuffer ExportChallenge(const char* data, int len) {
66876686
void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
66886687
Environment* env = Environment::GetCurrent(args);
66896688

6690-
size_t len = Buffer::Length(args[0]);
6691-
if (len == 0)
6689+
ArrayBufferViewContents<char> input(args[0]);
6690+
if (input.length() == 0)
66926691
return args.GetReturnValue().SetEmptyString();
66936692

6694-
char* data = Buffer::Data(args[0]);
6695-
CHECK_NOT_NULL(data);
6696-
6697-
OpenSSLBuffer cert = ExportChallenge(data, len);
6693+
OpenSSLBuffer cert = ExportChallenge(input.data(), input.length());
66986694
if (!cert)
66996695
return args.GetReturnValue().SetEmptyString();
67006696

@@ -6749,16 +6745,13 @@ void ConvertKey(const FunctionCallbackInfo<Value>& args) {
67496745

67506746

67516747
void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
6752-
CHECK(Buffer::HasInstance(args[0]));
6753-
CHECK(Buffer::HasInstance(args[1]));
6754-
6755-
size_t buf_length = Buffer::Length(args[0]);
6756-
CHECK_EQ(buf_length, Buffer::Length(args[1]));
6748+
ArrayBufferViewContents<char> buf1(args[0]);
6749+
ArrayBufferViewContents<char> buf2(args[1]);
67576750

6758-
const char* buf1 = Buffer::Data(args[0]);
6759-
const char* buf2 = Buffer::Data(args[1]);
6751+
CHECK_EQ(buf1.length(), buf2.length());
67606752

6761-
return args.GetReturnValue().Set(CRYPTO_memcmp(buf1, buf2, buf_length) == 0);
6753+
return args.GetReturnValue().Set(
6754+
CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.length()) == 0);
67626755
}
67636756

67646757
void InitCryptoOnce() {

src/node_http_parser_impl.h

+5-8
Original file line numberDiff line numberDiff line change
@@ -466,18 +466,15 @@ class Parser : public AsyncWrap, public StreamListener {
466466
CHECK(parser->current_buffer_.IsEmpty());
467467
CHECK_EQ(parser->current_buffer_len_, 0);
468468
CHECK_NULL(parser->current_buffer_data_);
469-
CHECK_EQ(Buffer::HasInstance(args[0]), true);
470469

471-
Local<Object> buffer_obj = args[0].As<Object>();
472-
char* buffer_data = Buffer::Data(buffer_obj);
473-
size_t buffer_len = Buffer::Length(buffer_obj);
470+
ArrayBufferViewContents<char> buffer(args[0]);
474471

475472
// This is a hack to get the current_buffer to the callbacks with the least
476473
// amount of overhead. Nothing else will run while http_parser_execute()
477474
// runs, therefore this pointer can be set and used for the execution.
478-
parser->current_buffer_ = buffer_obj;
475+
parser->current_buffer_ = args[0].As<Object>();
479476

480-
Local<Value> ret = parser->Execute(buffer_data, buffer_len);
477+
Local<Value> ret = parser->Execute(buffer.data(), buffer.length());
481478

482479
if (!ret.IsEmpty())
483480
args.GetReturnValue().Set(ret);
@@ -643,7 +640,7 @@ class Parser : public AsyncWrap, public StreamListener {
643640
}
644641

645642

646-
Local<Value> Execute(char* data, size_t len) {
643+
Local<Value> Execute(const char* data, size_t len) {
647644
EscapableHandleScope scope(env()->isolate());
648645

649646
current_buffer_len_ = len;
@@ -857,7 +854,7 @@ class Parser : public AsyncWrap, public StreamListener {
857854
bool got_exception_;
858855
Local<Object> current_buffer_;
859856
size_t current_buffer_len_;
860-
char* current_buffer_data_;
857+
const char* current_buffer_data_;
861858
#ifdef NODE_EXPERIMENTAL_HTTP
862859
unsigned int execute_depth_ = 0;
863860
bool pending_pause_ = false;

src/node_i18n.cc

+6-8
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,13 @@ class ConverterObject : public BaseObject, Converter {
205205

206206
ConverterObject* converter;
207207
ASSIGN_OR_RETURN_UNWRAP(&converter, args[0].As<Object>());
208-
SPREAD_BUFFER_ARG(args[1], input_obj);
208+
ArrayBufferViewContents<char> input(args[1]);
209209
int flags = args[2]->Uint32Value(env->context()).ToChecked();
210210

211211
UErrorCode status = U_ZERO_ERROR;
212212
MaybeStackBuffer<UChar> result;
213213
MaybeLocal<Object> ret;
214-
size_t limit = ucnv_getMinCharSize(converter->conv) *
215-
input_obj_length;
214+
size_t limit = ucnv_getMinCharSize(converter->conv) * input.length();
216215
if (limit > 0)
217216
result.AllocateSufficientStorage(limit);
218217

@@ -225,8 +224,8 @@ class ConverterObject : public BaseObject, Converter {
225224
}
226225
});
227226

228-
const char* source = input_obj_data;
229-
size_t source_length = input_obj_length;
227+
const char* source = input.data();
228+
size_t source_length = input.length();
230229

231230
if (converter->unicode_ && !converter->ignoreBOM_ && !converter->bomSeen_) {
232231
int32_t bomOffset = 0;
@@ -455,8 +454,7 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
455454
UErrorCode status = U_ZERO_ERROR;
456455
MaybeLocal<Object> result;
457456

458-
CHECK(Buffer::HasInstance(args[0]));
459-
SPREAD_BUFFER_ARG(args[0], ts_obj);
457+
ArrayBufferViewContents<char> input(args[0]);
460458
const enum encoding fromEncoding = ParseEncoding(isolate, args[1], BUFFER);
461459
const enum encoding toEncoding = ParseEncoding(isolate, args[2], BUFFER);
462460

@@ -490,7 +488,7 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
490488
}
491489

492490
result = tfn(env, EncodingName(fromEncoding), EncodingName(toEncoding),
493-
ts_obj_data, ts_obj_length, &status);
491+
input.data(), input.length(), &status);
494492
} else {
495493
status = U_ILLEGAL_ARGUMENT_ERROR;
496494
}

src/node_serdes.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ void SerializerContext::WriteRawBytes(const FunctionCallbackInfo<Value>& args) {
274274
ctx->env(), "source must be a TypedArray or a DataView");
275275
}
276276

277-
ctx->serializer_.WriteRawBytes(Buffer::Data(args[0]),
278-
Buffer::Length(args[0]));
277+
ArrayBufferViewContents<char> bytes(args[0]);
278+
ctx->serializer_.WriteRawBytes(bytes.data(), bytes.length());
279279
}
280280

281281
DeserializerContext::DeserializerContext(Environment* env,

src/tls_wrap.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ void TLSWrap::Receive(const FunctionCallbackInfo<Value>& args) {
187187
TLSWrap* wrap;
188188
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
189189

190-
CHECK(Buffer::HasInstance(args[0]));
191-
char* data = Buffer::Data(args[0]);
192-
size_t len = Buffer::Length(args[0]);
190+
ArrayBufferViewContents<char> buffer(args[0]);
191+
const char* data = buffer.data();
192+
size_t len = buffer.length();
193193
Debug(wrap, "Receiving %zu bytes injected from JS", len);
194194

195195
// Copy given buffer entirely or partiall if handle becomes closed

src/util-inl.h

+7
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,13 @@ ArrayBufferViewContents<T, S>::ArrayBufferViewContents(
495495
Read(value.As<v8::ArrayBufferView>());
496496
}
497497

498+
template <typename T, size_t S>
499+
ArrayBufferViewContents<T, S>::ArrayBufferViewContents(
500+
v8::Local<v8::Object> value) {
501+
CHECK(value->IsArrayBufferView());
502+
Read(value.As<v8::ArrayBufferView>());
503+
}
504+
498505
template <typename T, size_t S>
499506
ArrayBufferViewContents<T, S>::ArrayBufferViewContents(
500507
v8::Local<v8::ArrayBufferView> abv) {

0 commit comments

Comments
 (0)