Skip to content

Commit 817dc7d

Browse files
committed
src: perform minor cleanups on zlib code
- Use `final` to indicate the classes that we actually instantiate - Properly use `const` (and the necessary associated `const_cast` for zlib because we don’t define `ZLIB_CONST` and allow shared builds) - Store the JS callback in an internal field rather than a `Global` (which improves memory leak debugging capabilities, removes a potential future memory leak footgun, and aligns the code with the rest of the codebase more closely) - Other minor C++ cleanup
1 parent 64832c1 commit 817dc7d

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

src/node_zlib.cc

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ enum node_zlib_mode {
107107
BROTLI_ENCODE
108108
};
109109

110-
#define GZIP_HEADER_ID1 0x1f
111-
#define GZIP_HEADER_ID2 0x8b
110+
constexpr uint8_t GZIP_HEADER_ID1 = 0x1f;
111+
constexpr uint8_t GZIP_HEADER_ID2 = 0x8b;
112112

113113
struct CompressionError {
114114
CompressionError(const char* message, const char* code, int err)
@@ -127,14 +127,14 @@ struct CompressionError {
127127
inline bool IsError() const { return code != nullptr; }
128128
};
129129

130-
class ZlibContext : public MemoryRetainer {
130+
class ZlibContext final : public MemoryRetainer {
131131
public:
132132
ZlibContext() = default;
133133

134134
// Streaming-related, should be available for all compression libraries:
135135
void Close();
136136
void DoThreadPoolWork();
137-
void SetBuffers(char* in, uint32_t in_len, char* out, uint32_t out_len);
137+
void SetBuffers(const char* in, uint32_t in_len, char* out, uint32_t out_len);
138138
void SetFlush(int flush);
139139
void GetAfterWriteOffsets(uint32_t* avail_in, uint32_t* avail_out) const;
140140
CompressionError GetErrorInfo() const;
@@ -183,7 +183,7 @@ class BrotliContext : public MemoryRetainer {
183183
public:
184184
BrotliContext() = default;
185185

186-
void SetBuffers(char* in, uint32_t in_len, char* out, uint32_t out_len);
186+
void SetBuffers(const char* in, uint32_t in_len, char* out, uint32_t out_len);
187187
void SetFlush(int flush);
188188
void GetAfterWriteOffsets(uint32_t* avail_in, uint32_t* avail_out) const;
189189
inline void SetMode(node_zlib_mode mode) { mode_ = mode; }
@@ -193,7 +193,7 @@ class BrotliContext : public MemoryRetainer {
193193

194194
protected:
195195
node_zlib_mode mode_ = NONE;
196-
uint8_t* next_in_ = nullptr;
196+
const uint8_t* next_in_ = nullptr;
197197
uint8_t* next_out_ = nullptr;
198198
size_t avail_in_ = 0;
199199
size_t avail_out_ = 0;
@@ -251,6 +251,12 @@ class BrotliDecoderContext final : public BrotliContext {
251251
template <typename CompressionContext>
252252
class CompressionStream : public AsyncWrap, public ThreadPoolWork {
253253
public:
254+
enum InternalFields {
255+
kCompressionStreamBaseField = AsyncWrap::kInternalFieldCount,
256+
kWriteJSCallback,
257+
kInternalFieldCount
258+
};
259+
254260
CompressionStream(Environment* env, Local<Object> wrap)
255261
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_ZLIB),
256262
ThreadPoolWork(env),
@@ -259,7 +265,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
259265
}
260266

261267
~CompressionStream() override {
262-
CHECK_EQ(false, write_in_progress_ && "write in progress");
268+
CHECK(!write_in_progress_);
263269
Close();
264270
CHECK_EQ(zlib_memory_, 0);
265271
CHECK_EQ(unreported_allocations_, 0);
@@ -295,7 +301,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
295301
CHECK_EQ(args.Length(), 7);
296302

297303
uint32_t in_off, in_len, out_off, out_len, flush;
298-
char* in;
304+
const char* in;
299305
char* out;
300306

301307
CHECK_EQ(false, args[0]->IsUndefined() && "must provide flush value");
@@ -340,7 +346,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
340346

341347
template <bool async>
342348
void Write(uint32_t flush,
343-
char* in, uint32_t in_len,
349+
const char* in, uint32_t in_len,
344350
char* out, uint32_t out_len) {
345351
AllocScope alloc_scope(this);
346352

@@ -394,6 +400,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
394400

395401
// v8 land!
396402
void AfterThreadPoolWork(int status) override {
403+
DCHECK(init_done_);
397404
AllocScope alloc_scope(this);
398405
auto on_scope_leave = OnScopeLeave([&]() { Unref(); });
399406

@@ -416,9 +423,8 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
416423
UpdateWriteResult();
417424

418425
// call the write() cb
419-
Local<Function> cb = PersistentToLocal::Default(env->isolate(),
420-
write_js_callback_);
421-
MakeCallback(cb, 0, nullptr);
426+
Local<Value> cb = object()->GetInternalField(kWriteJSCallback);
427+
MakeCallback(cb.As<Function>(), 0, nullptr);
422428

423429
if (pending_close_)
424430
Close();
@@ -431,7 +437,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
431437
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
432438

433439
HandleScope scope(env->isolate());
434-
Local<Value> args[3] = {
440+
Local<Value> args[] = {
435441
OneByteString(env->isolate(), err.message),
436442
Integer::New(env->isolate(), err.err),
437443
OneByteString(env->isolate(), err.code)
@@ -465,7 +471,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
465471

466472
void InitStream(uint32_t* write_result, Local<Function> write_js_callback) {
467473
write_result_ = write_result;
468-
write_js_callback_.Reset(AsyncWrap::env()->isolate(), write_js_callback);
474+
object()->SetInternalField(kWriteJSCallback, write_js_callback);
469475
init_done_ = true;
470476
}
471477

@@ -540,14 +546,13 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork {
540546
bool closed_ = false;
541547
unsigned int refs_ = 0;
542548
uint32_t* write_result_ = nullptr;
543-
Global<Function> write_js_callback_;
544549
std::atomic<ssize_t> unreported_allocations_{0};
545550
size_t zlib_memory_ = 0;
546551

547552
CompressionContext ctx_;
548553
};
549554

550-
class ZlibStream : public CompressionStream<ZlibContext> {
555+
class ZlibStream final : public CompressionStream<ZlibContext> {
551556
public:
552557
ZlibStream(Environment* env, Local<Object> wrap, node_zlib_mode mode)
553558
: CompressionStream(env, wrap) {
@@ -646,7 +651,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
646651
};
647652

648653
template <typename CompressionContext>
649-
class BrotliCompressionStream : public CompressionStream<CompressionContext> {
654+
class BrotliCompressionStream final :
655+
public CompressionStream<CompressionContext> {
650656
public:
651657
BrotliCompressionStream(Environment* env,
652658
Local<Object> wrap,
@@ -857,10 +863,10 @@ void ZlibContext::DoThreadPoolWork() {
857863
}
858864

859865

860-
void ZlibContext::SetBuffers(char* in, uint32_t in_len,
866+
void ZlibContext::SetBuffers(const char* in, uint32_t in_len,
861867
char* out, uint32_t out_len) {
862868
strm_.avail_in = in_len;
863-
strm_.next_in = reinterpret_cast<Bytef*>(in);
869+
strm_.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(in));
864870
strm_.avail_out = out_len;
865871
strm_.next_out = reinterpret_cast<Bytef*>(out);
866872
}
@@ -1093,9 +1099,9 @@ CompressionError ZlibContext::SetParams(int level, int strategy) {
10931099
}
10941100

10951101

1096-
void BrotliContext::SetBuffers(char* in, uint32_t in_len,
1102+
void BrotliContext::SetBuffers(const char* in, uint32_t in_len,
10971103
char* out, uint32_t out_len) {
1098-
next_in_ = reinterpret_cast<uint8_t*>(in);
1104+
next_in_ = reinterpret_cast<const uint8_t*>(in);
10991105
next_out_ = reinterpret_cast<uint8_t*>(out);
11001106
avail_in_ = in_len;
11011107
avail_out_ = out_len;

0 commit comments

Comments
 (0)