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. PR-URL: https://github.com/nodejs/node/pull/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>
This commit is contained in:
parent
eb927fac38
commit
48ed65440c
@ -174,8 +174,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) {
|
||||
|
||||
/* Allocates and returns a new node_ares_task */
|
||||
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
|
||||
node_ares_task* task =
|
||||
static_cast<node_ares_task*>(node::Malloc(sizeof(*task)));
|
||||
auto task = node::Malloc<node_ares_task>(1);
|
||||
|
||||
if (task == nullptr) {
|
||||
/* Out of memory. */
|
||||
|
@ -979,7 +979,7 @@ Local<Value> WinapiErrnoException(Isolate* isolate,
|
||||
|
||||
void* ArrayBufferAllocator::Allocate(size_t size) {
|
||||
if (zero_fill_field_ || zero_fill_all_buffers)
|
||||
return node::Calloc(size, 1);
|
||||
return node::Calloc(size);
|
||||
else
|
||||
return node::Malloc(size);
|
||||
}
|
||||
|
@ -49,9 +49,6 @@
|
||||
THROW_AND_RETURN_IF_OOB(end <= end_max); \
|
||||
size_t length = end - start;
|
||||
|
||||
#define BUFFER_MALLOC(length) \
|
||||
zero_fill_all_buffers ? node::Calloc(length, 1) : node::Malloc(length)
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
|
||||
#define BSWAP_INTRINSIC_4(x) __builtin_bswap32(x)
|
||||
@ -89,6 +86,15 @@ namespace node {
|
||||
// if true, all Buffer and SlowBuffer instances will automatically zero-fill
|
||||
bool zero_fill_all_buffers = false;
|
||||
|
||||
namespace {
|
||||
|
||||
inline void* BufferMalloc(size_t length) {
|
||||
return zero_fill_all_buffers ? node::Calloc(length) :
|
||||
node::Malloc(length);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Buffer {
|
||||
|
||||
using v8::ArrayBuffer;
|
||||
@ -266,7 +272,7 @@ MaybeLocal<Object> New(Isolate* isolate,
|
||||
char* data = nullptr;
|
||||
|
||||
if (length > 0) {
|
||||
data = static_cast<char*>(BUFFER_MALLOC(length));
|
||||
data = static_cast<char*>(BufferMalloc(length));
|
||||
|
||||
if (data == nullptr)
|
||||
return Local<Object>();
|
||||
@ -278,7 +284,7 @@ MaybeLocal<Object> New(Isolate* isolate,
|
||||
free(data);
|
||||
data = nullptr;
|
||||
} else if (actual < length) {
|
||||
data = static_cast<char*>(node::Realloc(data, actual));
|
||||
data = node::Realloc(data, actual);
|
||||
CHECK_NE(data, nullptr);
|
||||
}
|
||||
}
|
||||
@ -312,7 +318,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
|
||||
|
||||
void* data;
|
||||
if (length > 0) {
|
||||
data = BUFFER_MALLOC(length);
|
||||
data = BufferMalloc(length);
|
||||
if (data == nullptr)
|
||||
return Local<Object>();
|
||||
} else {
|
||||
@ -1080,7 +1086,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
|
||||
offset,
|
||||
is_forward);
|
||||
} else if (enc == LATIN1) {
|
||||
uint8_t* needle_data = static_cast<uint8_t*>(node::Malloc(needle_length));
|
||||
uint8_t* needle_data = node::Malloc<uint8_t>(needle_length);
|
||||
if (needle_data == nullptr) {
|
||||
return args.GetReturnValue().Set(-1);
|
||||
}
|
||||
|
@ -2279,7 +2279,7 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
|
||||
size_t len = Buffer::Length(obj);
|
||||
|
||||
// OpenSSL takes control of the pointer after accepting it
|
||||
char* data = reinterpret_cast<char*>(node::Malloc(len));
|
||||
char* data = node::Malloc(len);
|
||||
CHECK_NE(data, nullptr);
|
||||
memcpy(data, resp, len);
|
||||
|
||||
@ -3330,7 +3330,7 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
|
||||
if (initialised_ || kind_ != kCipher || !auth_tag_)
|
||||
return false;
|
||||
*out_len = auth_tag_len_;
|
||||
*out = static_cast<char*>(node::Malloc(auth_tag_len_));
|
||||
*out = node::Malloc(auth_tag_len_);
|
||||
CHECK_NE(*out, nullptr);
|
||||
memcpy(*out, auth_tag_, auth_tag_len_);
|
||||
return true;
|
||||
@ -4906,7 +4906,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
|
||||
// NOTE: field_size is in bits
|
||||
int field_size = EC_GROUP_get_degree(ecdh->group_);
|
||||
size_t out_len = (field_size + 7) / 8;
|
||||
char* out = static_cast<char*>(node::Malloc(out_len));
|
||||
char* out = node::Malloc(out_len);
|
||||
CHECK_NE(out, nullptr);
|
||||
|
||||
int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
|
||||
@ -4942,7 +4942,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
|
||||
if (size == 0)
|
||||
return env->ThrowError("Failed to get public key length");
|
||||
|
||||
unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
|
||||
unsigned char* out = node::Malloc<unsigned char>(size);
|
||||
CHECK_NE(out, nullptr);
|
||||
|
||||
int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
|
||||
@ -4968,7 +4968,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
|
||||
return env->ThrowError("Failed to get ECDH private key");
|
||||
|
||||
int size = BN_num_bytes(b);
|
||||
unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
|
||||
unsigned char* out = node::Malloc<unsigned char>(size);
|
||||
CHECK_NE(out, nullptr);
|
||||
|
||||
if (size != BN_bn2bin(b, out)) {
|
||||
@ -5099,7 +5099,7 @@ class PBKDF2Request : public AsyncWrap {
|
||||
saltlen_(saltlen),
|
||||
salt_(salt),
|
||||
keylen_(keylen),
|
||||
key_(static_cast<char*>(node::Malloc(keylen))),
|
||||
key_(node::Malloc(keylen)),
|
||||
iter_(iter) {
|
||||
if (key() == nullptr)
|
||||
FatalError("node::PBKDF2Request()", "Out of Memory");
|
||||
@ -5262,7 +5262,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt");
|
||||
|
||||
pass = static_cast<char*>(node::Malloc(passlen));
|
||||
pass = node::Malloc(passlen);
|
||||
if (pass == nullptr) {
|
||||
FatalError("node::PBKDF2()", "Out of Memory");
|
||||
}
|
||||
@ -5274,7 +5274,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
salt = static_cast<char*>(node::Malloc(saltlen));
|
||||
salt = node::Malloc(saltlen);
|
||||
if (salt == nullptr) {
|
||||
FatalError("node::PBKDF2()", "Out of Memory");
|
||||
}
|
||||
@ -5367,7 +5367,7 @@ class RandomBytesRequest : public AsyncWrap {
|
||||
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
|
||||
error_(0),
|
||||
size_(size),
|
||||
data_(static_cast<char*>(node::Malloc(size))) {
|
||||
data_(node::Malloc(size)) {
|
||||
if (data() == nullptr)
|
||||
FatalError("node::RandomBytesRequest()", "Out of Memory");
|
||||
Wrap(object, this);
|
||||
@ -5594,8 +5594,7 @@ void GetCurves(const FunctionCallbackInfo<Value>& args) {
|
||||
EC_builtin_curve* curves;
|
||||
|
||||
if (num_curves) {
|
||||
curves = static_cast<EC_builtin_curve*>(node::Malloc(sizeof(*curves),
|
||||
num_curves));
|
||||
curves = node::Malloc<EC_builtin_curve>(num_curves);
|
||||
|
||||
CHECK_NE(curves, nullptr);
|
||||
|
||||
|
@ -148,7 +148,7 @@ void StreamWrap::OnAlloc(uv_handle_t* handle,
|
||||
|
||||
|
||||
void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) {
|
||||
buf->base = static_cast<char*>(node::Malloc(size));
|
||||
buf->base = node::Malloc(size);
|
||||
buf->len = size;
|
||||
|
||||
if (buf->base == nullptr && size > 0) {
|
||||
@ -204,7 +204,7 @@ void StreamWrap::OnReadImpl(ssize_t nread,
|
||||
return;
|
||||
}
|
||||
|
||||
char* base = static_cast<char*>(node::Realloc(buf->base, nread));
|
||||
char* base = node::Realloc(buf->base, nread);
|
||||
CHECK_LE(static_cast<size_t>(nread), buf->len);
|
||||
|
||||
if (pending == UV_TCP) {
|
||||
|
@ -53,8 +53,7 @@ class ExternString: public ResourceType {
|
||||
if (length == 0)
|
||||
return scope.Escape(String::Empty(isolate));
|
||||
|
||||
TypeName* new_data =
|
||||
static_cast<TypeName*>(node::Malloc(length, sizeof(*new_data)));
|
||||
TypeName* new_data = node::Malloc<TypeName>(length);
|
||||
if (new_data == nullptr) {
|
||||
return Local<String>();
|
||||
}
|
||||
@ -624,7 +623,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
|
||||
|
||||
case ASCII:
|
||||
if (contains_non_ascii(buf, buflen)) {
|
||||
char* out = static_cast<char*>(node::Malloc(buflen));
|
||||
char* out = node::Malloc(buflen);
|
||||
if (out == nullptr) {
|
||||
return Local<String>();
|
||||
}
|
||||
@ -659,7 +658,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
|
||||
|
||||
case BASE64: {
|
||||
size_t dlen = base64_encoded_size(buflen);
|
||||
char* dst = static_cast<char*>(node::Malloc(dlen));
|
||||
char* dst = node::Malloc(dlen);
|
||||
if (dst == nullptr) {
|
||||
return Local<String>();
|
||||
}
|
||||
@ -678,7 +677,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
|
||||
|
||||
case HEX: {
|
||||
size_t dlen = buflen * 2;
|
||||
char* dst = static_cast<char*>(node::Malloc(dlen));
|
||||
char* dst = node::Malloc(dlen);
|
||||
if (dst == nullptr) {
|
||||
return Local<String>();
|
||||
}
|
||||
|
@ -661,7 +661,7 @@ void TLSWrap::OnReadImpl(ssize_t nread,
|
||||
|
||||
|
||||
void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) {
|
||||
buf->base = static_cast<char*>(node::Malloc(suggested_size));
|
||||
buf->base = node::Malloc(suggested_size);
|
||||
CHECK_NE(buf->base, nullptr);
|
||||
buf->len = suggested_size;
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
|
||||
void UDPWrap::OnAlloc(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
buf->base = static_cast<char*>(node::Malloc(suggested_size));
|
||||
buf->base = node::Malloc(suggested_size);
|
||||
buf->len = suggested_size;
|
||||
|
||||
if (buf->base == nullptr && suggested_size > 0) {
|
||||
@ -416,7 +416,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
|
||||
return;
|
||||
}
|
||||
|
||||
char* base = static_cast<char*>(node::Realloc(buf->base, nread));
|
||||
char* base = node::Realloc(buf->base, nread);
|
||||
argv[2] = Buffer::New(env, base, nread).ToLocalChecked();
|
||||
argv[3] = AddressToJS(env, addr);
|
||||
wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv);
|
||||
|
@ -244,29 +244,30 @@ inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) {
|
||||
// that the standard allows them to either return a unique pointer or a
|
||||
// nullptr for zero-sized allocation requests. Normalize by always using
|
||||
// a nullptr.
|
||||
void* Realloc(void* pointer, size_t n, size_t size) {
|
||||
size_t full_size = MultiplyWithOverflowCheck(size, n);
|
||||
template <typename T>
|
||||
T* Realloc(T* pointer, size_t n) {
|
||||
size_t full_size = MultiplyWithOverflowCheck(sizeof(T), n);
|
||||
|
||||
if (full_size == 0) {
|
||||
free(pointer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return realloc(pointer, full_size);
|
||||
return static_cast<T*>(realloc(pointer, full_size));
|
||||
}
|
||||
|
||||
// As per spec realloc behaves like malloc if passed nullptr.
|
||||
void* Malloc(size_t n, size_t size) {
|
||||
template <typename T>
|
||||
T* Malloc(size_t n) {
|
||||
if (n == 0) n = 1;
|
||||
if (size == 0) size = 1;
|
||||
return Realloc(nullptr, n, size);
|
||||
return Realloc<T>(nullptr, n);
|
||||
}
|
||||
|
||||
void* Calloc(size_t n, size_t size) {
|
||||
template <typename T>
|
||||
T* Calloc(size_t n) {
|
||||
if (n == 0) n = 1;
|
||||
if (size == 0) size = 1;
|
||||
MultiplyWithOverflowCheck(size, n);
|
||||
return calloc(n, size);
|
||||
MultiplyWithOverflowCheck(sizeof(T), n);
|
||||
return static_cast<T*>(calloc(n, sizeof(T)));
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
15
src/util.h
15
src/util.h
@ -22,9 +22,16 @@ namespace node {
|
||||
// that the standard allows them to either return a unique pointer or a
|
||||
// nullptr for zero-sized allocation requests. Normalize by always using
|
||||
// a nullptr.
|
||||
inline void* Realloc(void* pointer, size_t n, size_t size = 1);
|
||||
inline void* Malloc(size_t n, size_t size = 1);
|
||||
inline void* Calloc(size_t n, size_t size = 1);
|
||||
template <typename T>
|
||||
inline T* Realloc(T* pointer, size_t n);
|
||||
template <typename T>
|
||||
inline T* Malloc(size_t n);
|
||||
template <typename T>
|
||||
inline T* Calloc(size_t n);
|
||||
|
||||
// Shortcuts for char*.
|
||||
inline char* Malloc(size_t n) { return Malloc<char>(n); }
|
||||
inline char* Calloc(size_t n) { return Calloc<char>(n); }
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define NO_RETURN __attribute__((noreturn))
|
||||
@ -285,7 +292,7 @@ class MaybeStackBuffer {
|
||||
if (storage <= kStackStorageSize) {
|
||||
buf_ = buf_st_;
|
||||
} else {
|
||||
buf_ = static_cast<T*>(Malloc(sizeof(T), storage));
|
||||
buf_ = Malloc<T>(storage);
|
||||
CHECK_NE(buf_, nullptr);
|
||||
}
|
||||
|
||||
|
@ -92,14 +92,16 @@ TEST(UtilTest, ToLower) {
|
||||
|
||||
TEST(UtilTest, Malloc) {
|
||||
using node::Malloc;
|
||||
EXPECT_NE(nullptr, Malloc<char>(0));
|
||||
EXPECT_NE(nullptr, Malloc<char>(1));
|
||||
EXPECT_NE(nullptr, Malloc(0));
|
||||
EXPECT_NE(nullptr, Malloc(1));
|
||||
}
|
||||
|
||||
TEST(UtilTest, Calloc) {
|
||||
using node::Calloc;
|
||||
EXPECT_NE(nullptr, Calloc(0, 0));
|
||||
EXPECT_NE(nullptr, Calloc(1, 0));
|
||||
EXPECT_NE(nullptr, Calloc(0, 1));
|
||||
EXPECT_NE(nullptr, Calloc(1, 1));
|
||||
}
|
||||
EXPECT_NE(nullptr, Calloc<char>(0));
|
||||
EXPECT_NE(nullptr, Calloc<char>(1));
|
||||
EXPECT_NE(nullptr, Calloc(0));
|
||||
EXPECT_NE(nullptr, Calloc(1));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user