Skip to content

Commit 4aec8cf

Browse files
addaleaxMylesBorins
authored andcommitted
src: pass desired return type to allocators
Pass the desired return type directly to the allocation functions, so that the resulting `static_cast` from `void*` becomes unneccessary and the return type can be use as a reasonable default value for the `size` parameter. Backport-PR-URL: #16587 PR-URL: #8482 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
1 parent 19f3ac9 commit 4aec8cf

11 files changed

+68
-57
lines changed

src/cares_wrap.cc

+7-10
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) {
175175

176176
/* Allocates and returns a new node_ares_task */
177177
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
178-
node_ares_task* task =
179-
static_cast<node_ares_task*>(node::Malloc(sizeof(*task)));
178+
auto task = node::Malloc<node_ares_task>(1);
180179

181180
if (task == nullptr) {
182181
/* Out of memory. */
@@ -329,11 +328,10 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) {
329328
alias_count++) {
330329
}
331330

332-
dest->h_aliases = static_cast<char**>(node::Malloc((alias_count + 1) *
333-
sizeof(char*)));
331+
dest->h_aliases = node::Malloc<char*>(alias_count + 1);
334332
for (size_t i = 0; i < alias_count; i++) {
335333
cur_alias_length = strlen(src->h_aliases[i]);
336-
dest->h_aliases[i] = static_cast<char*>(node::Malloc(cur_alias_length + 1));
334+
dest->h_aliases[i] = node::Malloc(cur_alias_length + 1);
337335
memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_length + 1);
338336
}
339337
dest->h_aliases[alias_count] = nullptr;
@@ -345,10 +343,9 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) {
345343
list_count++) {
346344
}
347345

348-
dest->h_addr_list = static_cast<char**>(node::Malloc((list_count + 1) *
349-
sizeof(char*)));
346+
dest->h_addr_list = node::Malloc<char*>(list_count + 1);
350347
for (size_t i = 0; i < list_count; i++) {
351-
dest->h_addr_list[i] = static_cast<char*>(node::Malloc(src->h_length));
348+
dest->h_addr_list[i] = node::Malloc(src->h_length);
352349
memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length);
353350
}
354351
dest->h_addr_list[list_count] = nullptr;
@@ -507,7 +504,7 @@ class QueryWrap : public AsyncWrap {
507504

508505
unsigned char* buf_copy = nullptr;
509506
if (status == ARES_SUCCESS) {
510-
buf_copy = static_cast<unsigned char*>(node::Malloc(answer_len));
507+
buf_copy = node::Malloc<unsigned char>(answer_len);
511508
memcpy(buf_copy, answer_buf, answer_len);
512509
}
513510

@@ -534,7 +531,7 @@ class QueryWrap : public AsyncWrap {
534531

535532
struct hostent* host_copy = nullptr;
536533
if (status == ARES_SUCCESS) {
537-
host_copy = static_cast<hostent*>(node::Malloc(sizeof(hostent)));
534+
host_copy = node::Malloc<hostent>(1);
538535
cares_wrap_hostent_cpy(host_copy, host);
539536
}
540537

src/node.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@ void* ArrayBufferAllocator::Allocate(size_t size) {
10541054
if (env_ == nullptr ||
10551055
!env_->array_buffer_allocator_info()->no_zero_fill() ||
10561056
zero_fill_all_buffers)
1057-
return node::Calloc(size, 1);
1057+
return node::Calloc(size);
10581058
env_->array_buffer_allocator_info()->reset_fill_flag();
10591059
return node::Malloc(size);
10601060
}

src/node_buffer.cc

+13-7
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,20 @@
4848
THROW_AND_RETURN_IF_OOB(end <= end_max); \
4949
size_t length = end - start;
5050

51-
#define BUFFER_MALLOC(length) \
52-
zero_fill_all_buffers ? node::Calloc(length, 1) : node::Malloc(length)
53-
5451
namespace node {
5552

5653
// if true, all Buffer and SlowBuffer instances will automatically zero-fill
5754
bool zero_fill_all_buffers = false;
5855

56+
namespace {
57+
58+
inline void* BufferMalloc(size_t length) {
59+
return zero_fill_all_buffers ? node::Calloc(length) :
60+
node::Malloc(length);
61+
}
62+
63+
} // namespace
64+
5965
namespace Buffer {
6066

6167
using v8::ArrayBuffer;
@@ -234,7 +240,7 @@ MaybeLocal<Object> New(Isolate* isolate,
234240
char* data = nullptr;
235241

236242
if (length > 0) {
237-
data = static_cast<char*>(BUFFER_MALLOC(length));
243+
data = static_cast<char*>(BufferMalloc(length));
238244

239245
if (data == nullptr)
240246
return Local<Object>();
@@ -246,7 +252,7 @@ MaybeLocal<Object> New(Isolate* isolate,
246252
free(data);
247253
data = nullptr;
248254
} else if (actual < length) {
249-
data = static_cast<char*>(node::Realloc(data, actual));
255+
data = node::Realloc(data, actual);
250256
CHECK_NE(data, nullptr);
251257
}
252258
}
@@ -280,7 +286,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
280286

281287
void* data;
282288
if (length > 0) {
283-
data = BUFFER_MALLOC(length);
289+
data = BufferMalloc(length);
284290
if (data == nullptr)
285291
return Local<Object>();
286292
} else {
@@ -1063,7 +1069,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
10631069
offset,
10641070
is_forward);
10651071
} else if (enc == LATIN1) {
1066-
uint8_t* needle_data = static_cast<uint8_t*>(node::Malloc(needle_length));
1072+
uint8_t* needle_data = node::Malloc<uint8_t>(needle_length);
10671073
if (needle_data == nullptr) {
10681074
return args.GetReturnValue().Set(-1);
10691075
}

src/node_crypto.cc

+10-11
Original file line numberDiff line numberDiff line change
@@ -2386,7 +2386,7 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
23862386
size_t len = Buffer::Length(obj);
23872387

23882388
// OpenSSL takes control of the pointer after accepting it
2389-
char* data = reinterpret_cast<char*>(node::Malloc(len));
2389+
char* data = node::Malloc(len);
23902390
CHECK_NE(data, nullptr);
23912391
memcpy(data, resp, len);
23922392

@@ -3466,7 +3466,7 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
34663466
if (initialised_ || kind_ != kCipher || !auth_tag_)
34673467
return false;
34683468
*out_len = auth_tag_len_;
3469-
*out = static_cast<char*>(node::Malloc(auth_tag_len_));
3469+
*out = node::Malloc(auth_tag_len_);
34703470
CHECK_NE(*out, nullptr);
34713471
memcpy(*out, auth_tag_, auth_tag_len_);
34723472
return true;
@@ -5138,7 +5138,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
51385138
// NOTE: field_size is in bits
51395139
int field_size = EC_GROUP_get_degree(ecdh->group_);
51405140
size_t out_len = (field_size + 7) / 8;
5141-
char* out = static_cast<char*>(node::Malloc(out_len));
5141+
char* out = node::Malloc(out_len);
51425142
CHECK_NE(out, nullptr);
51435143

51445144
int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
@@ -5174,7 +5174,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
51745174
if (size == 0)
51755175
return env->ThrowError("Failed to get public key length");
51765176

5177-
unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
5177+
unsigned char* out = node::Malloc<unsigned char>(size);
51785178
CHECK_NE(out, nullptr);
51795179

51805180
int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
@@ -5200,7 +5200,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
52005200
return env->ThrowError("Failed to get ECDH private key");
52015201

52025202
int size = BN_num_bytes(b);
5203-
unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
5203+
unsigned char* out = node::Malloc<unsigned char>(size);
52045204
CHECK_NE(out, nullptr);
52055205

52065206
if (size != BN_bn2bin(b, out)) {
@@ -5333,7 +5333,7 @@ class PBKDF2Request : public AsyncWrap {
53335333
saltlen_(saltlen),
53345334
salt_(salt),
53355335
keylen_(keylen),
5336-
key_(static_cast<char*>(node::Malloc(keylen))),
5336+
key_(node::Malloc(keylen)),
53375337
iter_(iter) {
53385338
if (key() == nullptr)
53395339
FatalError("node::PBKDF2Request()", "Out of Memory");
@@ -5496,7 +5496,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
54965496

54975497
THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt");
54985498

5499-
pass = static_cast<char*>(node::Malloc(passlen));
5499+
pass = node::Malloc(passlen);
55005500
if (pass == nullptr) {
55015501
FatalError("node::PBKDF2()", "Out of Memory");
55025502
}
@@ -5508,7 +5508,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
55085508
goto err;
55095509
}
55105510

5511-
salt = static_cast<char*>(node::Malloc(saltlen));
5511+
salt = node::Malloc(saltlen);
55125512
if (salt == nullptr) {
55135513
FatalError("node::PBKDF2()", "Out of Memory");
55145514
}
@@ -5601,7 +5601,7 @@ class RandomBytesRequest : public AsyncWrap {
56015601
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
56025602
error_(0),
56035603
size_(size),
5604-
data_(static_cast<char*>(node::Malloc(size))) {
5604+
data_(node::Malloc(size)) {
56055605
if (data() == nullptr)
56065606
FatalError("node::RandomBytesRequest()", "Out of Memory");
56075607
Wrap(object, this);
@@ -5828,8 +5828,7 @@ void GetCurves(const FunctionCallbackInfo<Value>& args) {
58285828
EC_builtin_curve* curves;
58295829

58305830
if (num_curves) {
5831-
curves = static_cast<EC_builtin_curve*>(node::Malloc(sizeof(*curves),
5832-
num_curves));
5831+
curves = node::Malloc<EC_builtin_curve>(num_curves);
58335832

58345833
CHECK_NE(curves, nullptr);
58355834

src/stream_wrap.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ void StreamWrap::OnAlloc(uv_handle_t* handle,
148148

149149

150150
void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) {
151-
buf->base = static_cast<char*>(node::Malloc(size));
151+
buf->base = node::Malloc(size);
152152
buf->len = size;
153153

154154
if (buf->base == nullptr && size > 0) {
@@ -204,7 +204,7 @@ void StreamWrap::OnReadImpl(ssize_t nread,
204204
return;
205205
}
206206

207-
char* base = static_cast<char*>(node::Realloc(buf->base, nread));
207+
char* base = node::Realloc(buf->base, nread);
208208
CHECK_LE(static_cast<size_t>(nread), buf->len);
209209

210210
if (pending == UV_TCP) {

src/string_bytes.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class ExternString: public ResourceType {
5353
if (length == 0)
5454
return scope.Escape(String::Empty(isolate));
5555

56-
TypeName* new_data =
57-
static_cast<TypeName*>(node::Malloc(length, sizeof(*new_data)));
56+
TypeName* new_data = node::Malloc<TypeName>(length);
5857
if (new_data == nullptr) {
5958
return Local<String>();
6059
}
@@ -610,7 +609,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
610609

611610
case ASCII:
612611
if (contains_non_ascii(buf, buflen)) {
613-
char* out = static_cast<char*>(node::Malloc(buflen));
612+
char* out = node::Malloc(buflen);
614613
if (out == nullptr) {
615614
return Local<String>();
616615
}
@@ -645,7 +644,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
645644

646645
case BASE64: {
647646
size_t dlen = base64_encoded_size(buflen);
648-
char* dst = static_cast<char*>(node::Malloc(dlen));
647+
char* dst = node::Malloc(dlen);
649648
if (dst == nullptr) {
650649
return Local<String>();
651650
}
@@ -664,7 +663,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
664663

665664
case HEX: {
666665
size_t dlen = buflen * 2;
667-
char* dst = static_cast<char*>(node::Malloc(dlen));
666+
char* dst = node::Malloc(dlen);
668667
if (dst == nullptr) {
669668
return Local<String>();
670669
}

src/tls_wrap.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ void TLSWrap::OnDestructImpl(void* ctx) {
663663

664664

665665
void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) {
666-
buf->base = static_cast<char*>(node::Malloc(suggested_size));
666+
buf->base = node::Malloc(suggested_size);
667667
CHECK_NE(buf->base, nullptr);
668668
buf->len = suggested_size;
669669
}

src/udp_wrap.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
373373
void UDPWrap::OnAlloc(uv_handle_t* handle,
374374
size_t suggested_size,
375375
uv_buf_t* buf) {
376-
buf->base = static_cast<char*>(node::Malloc(suggested_size));
376+
buf->base = node::Malloc(suggested_size);
377377
buf->len = suggested_size;
378378

379379
if (buf->base == nullptr && suggested_size > 0) {
@@ -415,7 +415,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
415415
return;
416416
}
417417

418-
char* base = static_cast<char*>(node::Realloc(buf->base, nread));
418+
char* base = node::Realloc(buf->base, nread);
419419
argv[2] = Buffer::New(env, base, nread).ToLocalChecked();
420420
argv[3] = AddressToJS(env, addr);
421421
wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv);

src/util-inl.h

+11-10
Original file line numberDiff line numberDiff line change
@@ -335,29 +335,30 @@ inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) {
335335
// that the standard allows them to either return a unique pointer or a
336336
// nullptr for zero-sized allocation requests. Normalize by always using
337337
// a nullptr.
338-
void* Realloc(void* pointer, size_t n, size_t size) {
339-
size_t full_size = MultiplyWithOverflowCheck(size, n);
338+
template <typename T>
339+
T* Realloc(T* pointer, size_t n) {
340+
size_t full_size = MultiplyWithOverflowCheck(sizeof(T), n);
340341

341342
if (full_size == 0) {
342343
free(pointer);
343344
return nullptr;
344345
}
345346

346-
return realloc(pointer, full_size);
347+
return static_cast<T*>(realloc(pointer, full_size));
347348
}
348349

349350
// As per spec realloc behaves like malloc if passed nullptr.
350-
void* Malloc(size_t n, size_t size) {
351+
template <typename T>
352+
T* Malloc(size_t n) {
351353
if (n == 0) n = 1;
352-
if (size == 0) size = 1;
353-
return Realloc(nullptr, n, size);
354+
return Realloc<T>(nullptr, n);
354355
}
355356

356-
void* Calloc(size_t n, size_t size) {
357+
template <typename T>
358+
T* Calloc(size_t n) {
357359
if (n == 0) n = 1;
358-
if (size == 0) size = 1;
359-
MultiplyWithOverflowCheck(size, n);
360-
return calloc(n, size);
360+
MultiplyWithOverflowCheck(sizeof(T), n);
361+
return static_cast<T*>(calloc(n, sizeof(T)));
361362
}
362363

363364
} // namespace node

src/util.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,16 @@ namespace node {
3131
// that the standard allows them to either return a unique pointer or a
3232
// nullptr for zero-sized allocation requests. Normalize by always using
3333
// a nullptr.
34-
inline void* Realloc(void* pointer, size_t n, size_t size = 1);
35-
inline void* Malloc(size_t n, size_t size = 1);
36-
inline void* Calloc(size_t n, size_t size = 1);
34+
template <typename T>
35+
inline T* Realloc(T* pointer, size_t n);
36+
template <typename T>
37+
inline T* Malloc(size_t n);
38+
template <typename T>
39+
inline T* Calloc(size_t n);
40+
41+
// Shortcuts for char*.
42+
inline char* Malloc(size_t n) { return Malloc<char>(n); }
43+
inline char* Calloc(size_t n) { return Calloc<char>(n); }
3744

3845
#ifdef __GNUC__
3946
#define NO_RETURN __attribute__((noreturn))
@@ -294,7 +301,7 @@ class MaybeStackBuffer {
294301
if (storage <= kStackStorageSize) {
295302
buf_ = buf_st_;
296303
} else {
297-
buf_ = static_cast<T*>(Malloc(sizeof(T), storage));
304+
buf_ = Malloc<T>(storage);
298305
CHECK_NE(buf_, nullptr);
299306
}
300307

test/cctest/test_util.cc

+6-4
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,16 @@ TEST(UtilTest, ToLower) {
9292

9393
TEST(UtilTest, Malloc) {
9494
using node::Malloc;
95+
EXPECT_NE(nullptr, Malloc<char>(0));
96+
EXPECT_NE(nullptr, Malloc<char>(1));
9597
EXPECT_NE(nullptr, Malloc(0));
9698
EXPECT_NE(nullptr, Malloc(1));
9799
}
98100

99101
TEST(UtilTest, Calloc) {
100102
using node::Calloc;
101-
EXPECT_NE(nullptr, Calloc(0, 0));
102-
EXPECT_NE(nullptr, Calloc(1, 0));
103-
EXPECT_NE(nullptr, Calloc(0, 1));
104-
EXPECT_NE(nullptr, Calloc(1, 1));
103+
EXPECT_NE(nullptr, Calloc<char>(0));
104+
EXPECT_NE(nullptr, Calloc<char>(1));
105+
EXPECT_NE(nullptr, Calloc(0));
106+
EXPECT_NE(nullptr, Calloc(1));
105107
}

0 commit comments

Comments
 (0)