-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add BindingData * add LogStream * add TransportParams PR-URL: #47348 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
- Loading branch information
Showing
10 changed files
with
1,082 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#ifndef SRC_BASE_OBJECT_TYPES_H_ | ||
#define SRC_BASE_OBJECT_TYPES_H_ | ||
|
||
#include <cinttypes> | ||
|
||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
namespace node { | ||
// List of internalBinding() data wrappers. The first argument should match | ||
// what the class passes to SET_BINDING_ID(), the second argument should match | ||
// the C++ class name. | ||
#define SERIALIZABLE_BINDING_TYPES(V) \ | ||
V(encoding_binding_data, encoding_binding::BindingData) \ | ||
V(fs_binding_data, fs::BindingData) \ | ||
V(v8_binding_data, v8_utils::BindingData) \ | ||
V(blob_binding_data, BlobBindingData) \ | ||
V(process_binding_data, process::BindingData) \ | ||
V(timers_binding_data, timers::BindingData) \ | ||
V(url_binding_data, url::BindingData) | ||
|
||
#define UNSERIALIZABLE_BINDING_TYPES(V) \ | ||
V(http2_binding_data, http2::BindingData) \ | ||
V(http_parser_binding_data, http_parser::BindingData) \ | ||
V(quic_binding_data, quic::BindingData) | ||
|
||
// List of (non-binding) BaseObjects that are serializable in the snapshot. | ||
// The first argument should match what the type passes to | ||
// SET_OBJECT_ID(), the second argument should match the C++ class | ||
// name. | ||
#define SERIALIZABLE_NON_BINDING_TYPES(V) \ | ||
V(util_weak_reference, util::WeakReference) | ||
|
||
// Helper list of all binding data wrapper types. | ||
#define BINDING_TYPES(V) \ | ||
SERIALIZABLE_BINDING_TYPES(V) \ | ||
UNSERIALIZABLE_BINDING_TYPES(V) | ||
|
||
// Helper list of all BaseObjects that implement snapshot support. | ||
#define SERIALIZABLE_OBJECT_TYPES(V) \ | ||
SERIALIZABLE_BINDING_TYPES(V) \ | ||
SERIALIZABLE_NON_BINDING_TYPES(V) | ||
|
||
#define V(TypeId, NativeType) k_##TypeId, | ||
enum class BindingDataType : uint8_t { BINDING_TYPES(V) kBindingDataTypeCount }; | ||
// Make sure that we put the bindings first so that we can also use the enums | ||
// for the bindings as index to the binding data store. | ||
enum class EmbedderObjectType : uint8_t { | ||
BINDING_TYPES(V) SERIALIZABLE_NON_BINDING_TYPES(V) | ||
// We do not need to know about all the unserializable non-binding types for | ||
// now so we do not list them. | ||
kEmbedderObjectTypeCount | ||
}; | ||
#undef V | ||
|
||
// For now, BaseObjects only need to call this when they implement snapshot | ||
// support. | ||
#define SET_OBJECT_ID(TypeId) \ | ||
static constexpr EmbedderObjectType type_int = EmbedderObjectType::k_##TypeId; | ||
|
||
// Binding data should call this so that they can be looked up from the binding | ||
// data store. | ||
#define SET_BINDING_ID(TypeId) \ | ||
static constexpr BindingDataType binding_type_int = \ | ||
BindingDataType::k_##TypeId; \ | ||
SET_OBJECT_ID(TypeId) \ | ||
static_assert(static_cast<uint8_t>(type_int) == \ | ||
static_cast<uint8_t>(binding_type_int)); | ||
|
||
} // namespace node | ||
|
||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#endif // SRC_BASE_OBJECT_TYPES_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC | ||
#include "bindingdata.h" | ||
#include <base_object-inl.h> | ||
#include <env-inl.h> | ||
#include <memory_tracker-inl.h> | ||
#include <nghttp3/nghttp3.h> | ||
#include <ngtcp2/ngtcp2.h> | ||
#include <node.h> | ||
#include <node_errors.h> | ||
#include <node_external_reference.h> | ||
#include <node_mem-inl.h> | ||
#include <node_realm-inl.h> | ||
#include <v8.h> | ||
|
||
namespace node { | ||
|
||
using v8::Function; | ||
using v8::FunctionCallbackInfo; | ||
using v8::FunctionTemplate; | ||
using v8::Local; | ||
using v8::Object; | ||
using v8::String; | ||
using v8::Value; | ||
|
||
namespace quic { | ||
|
||
BindingData& BindingData::Get(Environment* env) { | ||
return *Realm::GetBindingData<BindingData>(env->context()); | ||
} | ||
|
||
BindingData::operator ngtcp2_mem() { | ||
return MakeAllocator(); | ||
} | ||
|
||
BindingData::operator nghttp3_mem() { | ||
ngtcp2_mem allocator = *this; | ||
nghttp3_mem http3_allocator = { | ||
allocator.user_data, | ||
allocator.malloc, | ||
allocator.free, | ||
allocator.calloc, | ||
allocator.realloc, | ||
}; | ||
return http3_allocator; | ||
} | ||
|
||
void BindingData::CheckAllocatedSize(size_t previous_size) const { | ||
CHECK_GE(current_ngtcp2_memory_, previous_size); | ||
} | ||
|
||
void BindingData::IncreaseAllocatedSize(size_t size) { | ||
current_ngtcp2_memory_ += size; | ||
} | ||
|
||
void BindingData::DecreaseAllocatedSize(size_t size) { | ||
current_ngtcp2_memory_ -= size; | ||
} | ||
|
||
void BindingData::Initialize(Environment* env, Local<Object> target) { | ||
SetMethod(env->context(), target, "setCallbacks", SetCallbacks); | ||
Realm::GetCurrent(env->context()) | ||
->AddBindingData<BindingData>(env->context(), target); | ||
} | ||
|
||
void BindingData::RegisterExternalReferences( | ||
ExternalReferenceRegistry* registry) { | ||
registry->Register(SetCallbacks); | ||
} | ||
|
||
BindingData::BindingData(Realm* realm, Local<Object> object) | ||
: BaseObject(realm, object) { | ||
MakeWeak(); | ||
} | ||
|
||
void BindingData::MemoryInfo(MemoryTracker* tracker) const { | ||
#define V(name, _) tracker->TrackField(#name, name##_callback()); | ||
|
||
QUIC_JS_CALLBACKS(V) | ||
|
||
#undef V | ||
|
||
#define V(name, _) tracker->TrackField(#name, name##_string()); | ||
|
||
QUIC_STRINGS(V) | ||
|
||
#undef V | ||
} | ||
|
||
#define V(name) \ | ||
void BindingData::set_##name##_constructor_template( \ | ||
Local<FunctionTemplate> tmpl) { \ | ||
name##_constructor_template_.Reset(env()->isolate(), tmpl); \ | ||
} \ | ||
Local<FunctionTemplate> BindingData::name##_constructor_template() const { \ | ||
return PersistentToLocal::Default(env()->isolate(), \ | ||
name##_constructor_template_); \ | ||
} | ||
|
||
QUIC_CONSTRUCTORS(V) | ||
|
||
#undef V | ||
|
||
#define V(name, _) \ | ||
void BindingData::set_##name##_callback(Local<Function> fn) { \ | ||
name##_callback_.Reset(env()->isolate(), fn); \ | ||
} \ | ||
Local<Function> BindingData::name##_callback() const { \ | ||
return PersistentToLocal::Default(env()->isolate(), name##_callback_); \ | ||
} | ||
|
||
QUIC_JS_CALLBACKS(V) | ||
|
||
#undef V | ||
|
||
#define V(name, value) \ | ||
Local<String> BindingData::name##_string() const { \ | ||
if (name##_string_.IsEmpty()) \ | ||
name##_string_.Set(env()->isolate(), \ | ||
OneByteString(env()->isolate(), value)); \ | ||
return name##_string_.Get(env()->isolate()); \ | ||
} | ||
|
||
QUIC_STRINGS(V) | ||
|
||
#undef V | ||
|
||
#define V(name, value) \ | ||
Local<String> BindingData::on_##name##_string() const { \ | ||
if (on_##name##_string_.IsEmpty()) \ | ||
on_##name##_string_.Set( \ | ||
env()->isolate(), \ | ||
FIXED_ONE_BYTE_STRING(env()->isolate(), "on" #value)); \ | ||
return on_##name##_string_.Get(env()->isolate()); \ | ||
} | ||
|
||
QUIC_JS_CALLBACKS(V) | ||
|
||
#undef V | ||
|
||
void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) { | ||
auto env = Environment::GetCurrent(args); | ||
auto isolate = env->isolate(); | ||
BindingData& state = BindingData::Get(env); | ||
CHECK(args[0]->IsObject()); | ||
Local<Object> obj = args[0].As<Object>(); | ||
|
||
#define V(name, key) \ | ||
do { \ | ||
Local<Value> val; \ | ||
if (!obj->Get(env->context(), state.on_##name##_string()).ToLocal(&val) || \ | ||
!val->IsFunction()) { \ | ||
return THROW_ERR_MISSING_ARGS(isolate, "Missing Callback: on" #key); \ | ||
} \ | ||
state.set_##name##_callback(val.As<Function>()); \ | ||
} while (0); | ||
|
||
QUIC_JS_CALLBACKS(V) | ||
|
||
#undef V | ||
} | ||
|
||
} // namespace quic | ||
} // namespace node | ||
|
||
#endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC |
Oops, something went wrong.