From 46cb0da9bf43afde6b1ffc48a84be9ab11ae6a48 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Mon, 18 Nov 2019 19:07:33 +0200 Subject: [PATCH] http2: replace direct array usage with struct for js_fields_ PR-URL: https://github.com/nodejs/node/pull/30534 Fixes: https://github.com/nodejs/node/issues/30505 Reviewed-By: Anna Henningsen Reviewed-By: David Carlier Reviewed-By: James M Snell --- src/node_http2.cc | 16 +++++++++------- src/node_http2.h | 18 +++++++++++++----- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/node_http2.cc b/src/node_http2.cc index d110ada7235548..66a3a9e0f59555 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -651,7 +651,9 @@ Http2Session::Http2Session(Environment* env, { // Make the js_fields_ property accessible to JS land. Local ab = - ArrayBuffer::New(env->isolate(), js_fields_, kSessionUint8FieldCount); + ArrayBuffer::New(env->isolate(), + reinterpret_cast(&js_fields_), + kSessionUint8FieldCount); Local uint8_arr = Uint8Array::New(ab, 0, kSessionUint8FieldCount); USE(wrap->Set(env->context(), env->fields_string(), uint8_arr)); @@ -1082,7 +1084,7 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle, if (error_code == NGHTTP2_ERR_SESSION_CLOSING || error_code == NGHTTP2_ERR_STREAM_CLOSED || error_code == NGHTTP2_ERR_STREAM_CLOSING || - session->js_fields_[kSessionFrameErrorListenerCount] == 0) { + session->js_fields_.frame_error_listener_count == 0) { return 0; } @@ -1388,7 +1390,7 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) { // are considered advisory only, so this has no real effect other than to // simply let user code know that the priority has changed. void Http2Session::HandlePriorityFrame(const nghttp2_frame* frame) { - if (js_fields_[kSessionPriorityListenerCount] == 0) return; + if (js_fields_.priority_listener_count == 0) return; Isolate* isolate = env()->isolate(); HandleScope scope(isolate); Local context = env()->context(); @@ -1458,7 +1460,7 @@ void Http2Session::HandleGoawayFrame(const nghttp2_frame* frame) { // Called by OnFrameReceived when a complete ALTSVC frame has been received. void Http2Session::HandleAltSvcFrame(const nghttp2_frame* frame) { - if (!(js_fields_[kBitfield] & (1 << kSessionHasAltsvcListeners))) return; + if (!(js_fields_.bitfield & (1 << kSessionHasAltsvcListeners))) return; Isolate* isolate = env()->isolate(); HandleScope scope(isolate); Local context = env()->context(); @@ -1537,7 +1539,7 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { return; } - if (!(js_fields_[kBitfield] & (1 << kSessionHasPingListeners))) return; + if (!(js_fields_.bitfield & (1 << kSessionHasPingListeners))) return; // Notify the session that a ping occurred arg = Buffer::Copy(env(), reinterpret_cast(frame->ping.opaque_data), @@ -1549,8 +1551,8 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) { bool ack = frame->hd.flags & NGHTTP2_FLAG_ACK; if (!ack) { - js_fields_[kBitfield] &= ~(1 << kSessionRemoteSettingsIsUpToDate); - if (!(js_fields_[kBitfield] & (1 << kSessionHasRemoteSettingsListeners))) + js_fields_.bitfield &= ~(1 << kSessionRemoteSettingsIsUpToDate); + if (!(js_fields_.bitfield & (1 << kSessionHasRemoteSettingsListeners))) return; // This is not a SETTINGS acknowledgement, notify and return MakeCallback(env()->http2session_on_settings_function(), 0, nullptr); diff --git a/src/node_http2.h b/src/node_http2.h index 0b5e3d3ab88c2d..4567b1dab81b35 100644 --- a/src/node_http2.h +++ b/src/node_http2.h @@ -675,15 +675,23 @@ class Http2Stream::Provider::Stream : public Http2Stream::Provider { void* user_data); }; +typedef struct { + uint8_t bitfield; + uint8_t priority_listener_count; + uint8_t frame_error_listener_count; +} SessionJSFields; + // Indices for js_fields_, which serves as a way to communicate data with JS // land fast. In particular, we store information about the number/presence // of certain event listeners in JS, and skip calls from C++ into JS if they // are missing. enum SessionUint8Fields { - kBitfield, // See below - kSessionPriorityListenerCount, - kSessionFrameErrorListenerCount, - kSessionUint8FieldCount + kBitfield = offsetof(SessionJSFields, bitfield), // See below + kSessionPriorityListenerCount = + offsetof(SessionJSFields, priority_listener_count), + kSessionFrameErrorListenerCount = + offsetof(SessionJSFields, frame_error_listener_count), + kSessionUint8FieldCount = sizeof(SessionJSFields) }; enum SessionBitfieldFlags { @@ -972,7 +980,7 @@ class Http2Session : public AsyncWrap, public StreamListener { nghttp2_session* session_; // JS-accessible numeric fields, as indexed by SessionUint8Fields. - uint8_t js_fields_[kSessionUint8FieldCount] = {}; + SessionJSFields js_fields_ = {}; // The session type: client or server nghttp2_session_type session_type_;