Skip to content

Commit a3e1371

Browse files
committed
squash! src: retrieve binding data from the context
Co-authored-by: Anna Henningsen <[email protected]>
1 parent de409d8 commit a3e1371

14 files changed

+113
-115
lines changed

src/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,13 @@ Some internal bindings, such as the HTTP parser, maintain internal state that
402402
only affects that particular binding. In that case, one common way to store
403403
that state is through the use of `Environment::BindingScope`, which gives all
404404
new functions created within it access to an object for storing such state.
405-
That object is always a `BindingDataBase`.
405+
That object is always a [`BaseObject`][].
406406
407407
```c++
408408
// In the HTTP parser source code file:
409-
class BindingData : public BindingDataBase {
409+
class BindingData : public BaseObject {
410410
public:
411-
BindingData(Environment* env, Local<Object> obj) : BindingDataBase(env, obj) {}
411+
BindingData(Environment* env, Local<Object> obj) : BaseObject(env, obj) {}
412412
413413
std::vector<char> parser_buffer;
414414
bool parser_buffer_in_use = false;
@@ -418,7 +418,7 @@ class BindingData : public BindingDataBase {
418418
419419
// Available for binding functions, e.g. the HTTP Parser constructor:
420420
static void New(const FunctionCallbackInfo<Value>& args) {
421-
BindingData* binding_data = BindingDataBase::Unwrap<BindingData>(args);
421+
BindingData* binding_data = Environment::GetBindingData<BindingData>(args);
422422
new Parser(binding_data, args.This());
423423
}
424424
@@ -429,7 +429,7 @@ void InitializeHttpParser(Local<Object> target,
429429
Local<Context> context,
430430
void* priv) {
431431
Environment* env = Environment::GetCurrent(context);
432-
Environment::BindingScope<BindingData> binding_scope(env, context, target);
432+
Environment::BindingScope<BindingData> binding_scope(context, target);
433433
if (!binding_scope) return;
434434
BindingData* binding_data = binding_scope.data;
435435

src/env-inl.h

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ inline void Environment::AssignToContext(v8::Local<v8::Context> context,
289289
ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
290290
// Used to retrieve bindings
291291
context->SetAlignedPointerInEmbedderData(
292-
ContextEmbedderIndex::KBindingListIndex, &(this->bindings_));
292+
ContextEmbedderIndex::kBindingListIndex, &(this->bindings_));
293293

294294
#if HAVE_INSPECTOR
295295
inspector_agent()->ContextCreated(context, info);
@@ -322,74 +322,69 @@ inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
322322

323323
inline Environment* Environment::GetCurrent(
324324
const v8::FunctionCallbackInfo<v8::Value>& info) {
325-
return BindingDataBase::Unwrap<BindingDataBase>(info)->env();
325+
return GetCurrent(info.GetIsolate()->GetCurrentContext());
326326
}
327327

328328
template <typename T>
329329
inline Environment* Environment::GetCurrent(
330330
const v8::PropertyCallbackInfo<T>& info) {
331-
return BindingDataBase::Unwrap<BindingDataBase>(info)->env();
331+
return GetCurrent(info.GetIsolate()->GetCurrentContext());
332332
}
333333

334-
inline BindingDataBase::BindingDataBase(Environment* env,
335-
v8::Local<v8::Object> target)
336-
: BaseObject(env, target) {}
337-
338334
template <typename T, typename U>
339-
inline T* BindingDataBase::Unwrap(const v8::PropertyCallbackInfo<U>& info) {
340-
return Unwrap<T>(info.GetIsolate()->GetCurrentContext(), info.Data());
335+
inline T* Environment::GetBindingData(const v8::PropertyCallbackInfo<U>& info) {
336+
return GetBindingData<T>(info.GetIsolate()->GetCurrentContext(), info.Data());
341337
}
342338

343339
template <typename T>
344-
inline T* BindingDataBase::Unwrap(
340+
inline T* Environment::GetBindingData(
345341
const v8::FunctionCallbackInfo<v8::Value>& info) {
346-
return Unwrap<T>(info.GetIsolate()->GetCurrentContext(), info.Data());
342+
return GetBindingData<T>(info.GetIsolate()->GetCurrentContext(), info.Data());
347343
}
348344

349345
template <typename T>
350-
inline T* BindingDataBase::Unwrap(v8::Local<v8::Context> context,
351-
v8::Local<v8::Value> val) {
352-
CHECK(val->IsUint32());
346+
inline T* Environment::GetBindingData(v8::Local<v8::Context> context,
347+
v8::Local<v8::Value> val) {
348+
DCHECK(val->IsUint32());
353349
uint32_t index = val.As<v8::Uint32>()->Value();
354-
std::vector<BindingDataBase*>* list =
355-
static_cast<std::vector<BindingDataBase*>*>(
356-
context->GetAlignedPointerFromEmbedderData(
357-
ContextEmbedderIndex::KBindingListIndex));
358-
CHECK_GT(list->size(), index);
359-
T* result = static_cast<T*>(list->at(index));
350+
BindingDataList* list = static_cast<BindingDataList*>(
351+
context->GetAlignedPointerFromEmbedderData(
352+
ContextEmbedderIndex::kBindingListIndex));
353+
DCHECK_NOT_NULL(list);
354+
DCHECK_GT(list->size(), index);
355+
T* result = static_cast<T*>(list->at(index).get());
356+
DCHECK_NOT_NULL(result);
357+
DCHECK_EQ(result->env(), GetCurrent(context));
360358
return result;
361359
}
362360

363361
template <typename T>
364-
inline v8::Local<v8::Uint32> BindingDataBase::New(
365-
Environment* env,
362+
inline std::pair<T*, uint32_t> Environment::NewBindingData(
366363
v8::Local<v8::Context> context,
367364
v8::Local<v8::Object> target) {
368-
T* data = new T(env, target);
369-
// This won't compile if T is not a BindingDataBase subclass.
370-
BindingDataBase* item = static_cast<BindingDataBase*>(data);
371-
std::vector<BindingDataBase*>* list =
372-
static_cast<std::vector<BindingDataBase*>*>(
373-
context->GetAlignedPointerFromEmbedderData(
374-
ContextEmbedderIndex::KBindingListIndex));
365+
DCHECK_EQ(GetCurrent(context), this);
366+
// This won't compile if T is not a BaseObject subclass.
367+
BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target);
368+
BindingDataList* list = static_cast<BindingDataList*>(
369+
context->GetAlignedPointerFromEmbedderData(
370+
ContextEmbedderIndex::kBindingListIndex));
371+
DCHECK_NOT_NULL(list);
375372
size_t index = list->size();
376-
list->push_back(item);
377-
return v8::Integer::NewFromUnsigned(env->isolate(), index).As<v8::Uint32>();
373+
list->emplace_back(item);
374+
return std::make_pair(item.get(), index);
378375
}
379376

380377
template <typename T>
381-
Environment::BindingScope<T>::BindingScope(Environment* env,
382-
v8::Local<v8::Context> context,
378+
Environment::BindingScope<T>::BindingScope(v8::Local<v8::Context> context,
383379
v8::Local<v8::Object> target)
384-
: env(env) {
385-
v8::Local<v8::Uint32> index = BindingDataBase::New<T>(env, context, target);
386-
data = BindingDataBase::Unwrap<T>(context, index);
387-
env->set_current_callback_data(index);
380+
: env(Environment::GetCurrent(context)) {
381+
std::tie(data, env->current_callback_data_) =
382+
env->NewBindingData<T>(context, target);
388383
}
389384

390385
template <typename T>
391386
Environment::BindingScope<T>::~BindingScope() {
392-
env->set_current_callback_data(env->default_callback_data());
387+
env->current_callback_data_ = env->default_callback_data_;
393388
}
394389

395390
inline Environment* Environment::GetThreadLocalEnv() {
@@ -1299,12 +1294,20 @@ void Environment::set_process_exit_handler(
12991294
}
13001295
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
13011296
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1302-
ENVIRONMENT_CALLBACK_DATA(V)
13031297
#undef V
13041298

1305-
inline v8::Local<v8::Context> Environment::context() const {
1306-
return PersistentToLocal::Strong(context_);
1307-
}
1299+
v8::Local<v8::Context> Environment::context() const {
1300+
return PersistentToLocal::Strong(context_);
1301+
}
1302+
1303+
v8::Local<v8::Value> Environment::as_callback_data() const {
1304+
return v8::Integer::NewFromUnsigned(isolate(), default_callback_data_);
1305+
}
1306+
1307+
v8::Local<v8::Value> Environment::current_callback_data() const {
1308+
return v8::Integer::NewFromUnsigned(isolate(), current_callback_data_);
1309+
}
1310+
13081311
} // namespace node
13091312

13101313
// These two files depend on each other. Including base_object-inl.h after this

src/env.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ using v8::String;
5050
using v8::Symbol;
5151
using v8::TracingController;
5252
using v8::TryCatch;
53-
using v8::Uint32;
5453
using v8::Undefined;
5554
using v8::Value;
5655
using worker::Worker;
@@ -262,10 +261,10 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
262261
USE(cb->Call(env_->context(), Undefined(isolate), arraysize(args), args));
263262
}
264263

265-
class NoBindingData : public BindingDataBase {
264+
class NoBindingData : public BaseObject {
266265
public:
267266
NoBindingData(Environment* env, Local<Object> obj)
268-
: BindingDataBase(env, obj) {}
267+
: BaseObject(env, obj) {}
269268

270269
SET_NO_MEMORY_INFO()
271270
SET_MEMORY_INFO_NAME(NoBindingData)
@@ -285,9 +284,9 @@ void Environment::CreateProperties() {
285284
set_binding_data_ctor_template(templ);
286285
Local<Function> ctor = templ->GetFunction(ctx).ToLocalChecked();
287286
Local<Object> obj = ctor->NewInstance(ctx).ToLocalChecked();
288-
Local<Uint32> index = BindingDataBase::New<NoBindingData>(this, ctx, obj);
289-
set_default_callback_data(index);
290-
set_current_callback_data(index);
287+
uint32_t index = NewBindingData<NoBindingData>(ctx, obj).second;
288+
default_callback_data_ = index;
289+
current_callback_data_ = index;
291290
}
292291

293292
// Store primordials setup by the per-context script in the environment.
@@ -678,6 +677,8 @@ void Environment::RunCleanup() {
678677
started_cleanup_ = true;
679678
TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment),
680679
"RunCleanup", this);
680+
bindings_.clear();
681+
initial_base_object_count_ = 0;
681682
CleanupHandles();
682683

683684
while (!cleanup_hooks_.empty()) {
@@ -1137,7 +1138,6 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
11371138
#define V(PropertyName, TypeName) \
11381139
tracker->TrackField(#PropertyName, PropertyName());
11391140
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1140-
ENVIRONMENT_CALLBACK_DATA(V)
11411141
#undef V
11421142

11431143
// FIXME(joyeecheung): track other fields in Environment.

src/env.h

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,6 @@ constexpr size_t kFsStatsBufferLength =
419419
V(write_wrap_template, v8::ObjectTemplate) \
420420
V(worker_heap_snapshot_taker_template, v8::ObjectTemplate)
421421

422-
#define ENVIRONMENT_CALLBACK_DATA(V) \
423-
V(default_callback_data, v8::Uint32) \
424-
V(current_callback_data, v8::Uint32)
425-
426422
#define ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) \
427423
V(async_hooks_after_function, v8::Function) \
428424
V(async_hooks_before_function, v8::Function) \
@@ -826,28 +822,6 @@ class CleanupHookCallback {
826822
uint64_t insertion_order_counter_;
827823
};
828824

829-
class BindingDataBase : public BaseObject {
830-
public:
831-
// Exposed for subclasses
832-
inline BindingDataBase(Environment* env, v8::Local<v8::Object> target);
833-
// Unwrap a subclass T object from a v8::Value which needs to be an
834-
// v8::Uint32
835-
template <typename T, typename U>
836-
static inline T* Unwrap(const v8::PropertyCallbackInfo<U>& info);
837-
template <typename T>
838-
static inline T* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& info);
839-
840-
template <typename T>
841-
static inline T* Unwrap(v8::Local<v8::Context> context,
842-
v8::Local<v8::Value> val);
843-
// Create a BindingData of subclass T, put it into the context binding list,
844-
// return the index as v8::Integer
845-
template <typename T>
846-
static inline v8::Local<v8::Uint32> New(Environment* env,
847-
v8::Local<v8::Context> context,
848-
v8::Local<v8::Object> target);
849-
};
850-
851825
class Environment : public MemoryRetainer {
852826
public:
853827
Environment(const Environment&) = delete;
@@ -890,11 +864,10 @@ class Environment : public MemoryRetainer {
890864

891865
// Methods created using SetMethod(), SetPrototypeMethod(), etc. inside
892866
// this scope can access the created T* object using
893-
// Unwrap<T>(args.Data()) later.
867+
// GetBindingData<T>(args.Data()) later.
894868
template <typename T>
895869
struct BindingScope {
896-
explicit inline BindingScope(Environment* env,
897-
v8::Local<v8::Context> context,
870+
explicit inline BindingScope(v8::Local<v8::Context> context,
898871
v8::Local<v8::Object> target);
899872
inline ~BindingScope();
900873

@@ -905,6 +878,25 @@ class Environment : public MemoryRetainer {
905878
inline bool operator !() const { return data == nullptr; }
906879
};
907880

881+
template <typename T, typename U>
882+
static inline T* GetBindingData(const v8::PropertyCallbackInfo<U>& info);
883+
template <typename T>
884+
static inline T* GetBindingData(
885+
const v8::FunctionCallbackInfo<v8::Value>& info);
886+
887+
// Unwrap a subclass T object from a v8::Value which needs to be an
888+
// v8::Uint32
889+
template <typename T>
890+
static inline T* GetBindingData(v8::Local<v8::Context> context,
891+
v8::Local<v8::Value> val);
892+
// Create a BindingData of subclass T, put it into the context binding list,
893+
// return the index as an integer
894+
template <typename T>
895+
inline std::pair<T*, uint32_t> NewBindingData(v8::Local<v8::Context> context,
896+
v8::Local<v8::Object> target);
897+
898+
typedef std::vector<BaseObjectPtr<BaseObject>> BindingDataList;
899+
908900
static uv_key_t thread_local_env;
909901
static inline Environment* GetThreadLocalEnv();
910902

@@ -1149,12 +1141,13 @@ class Environment : public MemoryRetainer {
11491141
#define V(PropertyName, TypeName) \
11501142
inline v8::Local<TypeName> PropertyName() const; \
11511143
inline void set_ ## PropertyName(v8::Local<TypeName> value);
1152-
ENVIRONMENT_CALLBACK_DATA(V)
11531144
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
11541145
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
11551146
#undef V
11561147

11571148
inline v8::Local<v8::Context> context() const;
1149+
inline v8::Local<v8::Value> as_callback_data() const;
1150+
inline v8::Local<v8::Value> current_callback_data() const;
11581151

11591152
#if HAVE_INSPECTOR
11601153
inline inspector::Agent* inspector_agent() const {
@@ -1450,7 +1443,7 @@ class Environment : public MemoryRetainer {
14501443
void RequestInterruptFromV8();
14511444
static void CheckImmediate(uv_check_t* handle);
14521445

1453-
std::vector<BindingDataBase*> bindings_;
1446+
BindingDataList bindings_;
14541447

14551448
// Use an unordered_set, so that we have efficient insertion and removal.
14561449
std::unordered_set<CleanupHookCallback,
@@ -1470,13 +1463,15 @@ class Environment : public MemoryRetainer {
14701463
void ForEachBaseObject(T&& iterator);
14711464

14721465
#define V(PropertyName, TypeName) v8::Global<TypeName> PropertyName ## _;
1473-
ENVIRONMENT_CALLBACK_DATA(V)
14741466
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
14751467
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
14761468
#undef V
14771469

14781470
v8::Global<v8::Context> context_;
14791471

1472+
uint32_t default_callback_data_;
1473+
uint32_t current_callback_data_;
1474+
14801475
// Keeps the main script source alive is one was passed to LoadEnvironment().
14811476
// We should probably find a way to just use plain `v8::String`s created from
14821477
// the source passed to LoadEnvironment() directly instead.

src/node_context_data.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ enum ContextEmbedderIndex {
3434
kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX,
3535
kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX,
3636
kContextTag = NODE_CONTEXT_TAG,
37-
KBindingListIndex = NODE_BINDING_LIST_INDEX
37+
kBindingListIndex = NODE_BINDING_LIST_INDEX
3838
};
3939

4040
} // namespace node

src/node_file-inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ FSReqBase* GetReqWrap(const v8::FunctionCallbackInfo<v8::Value>& args,
227227
return Unwrap<FSReqBase>(value.As<v8::Object>());
228228
}
229229

230-
BindingData* binding_data = BindingDataBase::Unwrap<BindingData>(args);
230+
BindingData* binding_data = Environment::GetBindingData<BindingData>(args);
231231
Environment* env = binding_data->env();
232232
if (value->StrictEquals(env->fs_use_promises_symbol())) {
233233
if (use_bigint) {

0 commit comments

Comments
 (0)