Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: extract common context embedder tag checks #44258

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 1 addition & 10 deletions src/env-inl.h
Expand Up @@ -177,16 +177,7 @@ inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
}

inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
if (UNLIKELY(context.IsEmpty())) {
return nullptr;
}
if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
ContextEmbedderIndex::kContextTag)) {
return nullptr;
}
if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextTag) !=
Environment::kNodeContextTagPtr)) {
if (UNLIKELY(!ContextEmbedderTag::IsNodeContext(context))) {
return nullptr;
}
return static_cast<Environment*>(
Expand Down
10 changes: 4 additions & 6 deletions src/env.cc
Expand Up @@ -61,9 +61,9 @@ using v8::WeakCallbackInfo;
using v8::WeakCallbackType;
using worker::Worker;

int const Environment::kNodeContextTag = 0x6e6f64;
void* const Environment::kNodeContextTagPtr = const_cast<void*>(
static_cast<const void*>(&Environment::kNodeContextTag));
int const ContextEmbedderTag::kNodeContextTag = 0x6e6f64;
void* const ContextEmbedderTag::kNodeContextTagPtr = const_cast<void*>(
static_cast<const void*>(&ContextEmbedderTag::kNodeContextTag));

void AsyncHooks::SetJSPromiseHooks(Local<Function> init,
Local<Function> before,
Expand Down Expand Up @@ -512,11 +512,9 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {

void Environment::AssignToContext(Local<v8::Context> context,
const ContextInfo& info) {
ContextEmbedderTag::TagNodeContext(context);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this should be done at the end of this method and the tagging should not be done before other fields are initialized, in case the ContextCreated call below invokes anything that attempts to access context fields, though it wouldn't be a problem until #44252 which makes it possible to fire ContextCreated() on contexts that have a global object with interceptors that attempt to access context fields, and the problem predates this PR anyway , so I am good with leaving it for that PR instead.

context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kEnvironment,
this);
// Used by Environment::GetCurrent to know that we are on a node context.
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kContextTag,
Environment::kNodeContextTagPtr);
// Used to retrieve bindings
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kBindingListIndex, &(this->bindings_));
Expand Down
3 changes: 0 additions & 3 deletions src/env.h
Expand Up @@ -1573,9 +1573,6 @@ class Environment : public MemoryRetainer {
uint64_t thread_id_;
std::unordered_set<worker::Worker*> sub_worker_contexts_;

static void* const kNodeContextTagPtr;
static int const kNodeContextTag;

#if HAVE_INSPECTOR
std::unique_ptr<inspector::Agent> inspector_agent_;
bool is_in_inspector_console_call_ = false;
Expand Down
55 changes: 47 additions & 8 deletions src/node_context_data.h
Expand Up @@ -3,6 +3,9 @@

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "util.h"
#include "v8.h"

namespace node {

// Pick an index that's hopefully out of the way when we're embedded inside
Expand All @@ -21,26 +24,62 @@ namespace node {
#define NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX 34
#endif

#ifndef NODE_CONTEXT_TAG
#define NODE_CONTEXT_TAG 35
#endif

#ifndef NODE_BINDING_LIST
#define NODE_BINDING_LIST_INDEX 36
#define NODE_BINDING_LIST_INDEX 35
#endif

#ifndef NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX
#define NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX 37
#define NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX 36
#endif

// NODE_CONTEXT_TAG must be greater than any embedder indexes so that a single
// check on the number of embedder data fields can assure the presence of all
// embedder indexes.
#ifndef NODE_CONTEXT_TAG
#define NODE_CONTEXT_TAG 37
#endif

enum ContextEmbedderIndex {
kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX,
kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX,
kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX,
kContextTag = NODE_CONTEXT_TAG,
kBindingListIndex = NODE_BINDING_LIST_INDEX,
kAllowCodeGenerationFromStrings =
NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX
NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX,
kContextTag = NODE_CONTEXT_TAG,
};

class ContextEmbedderTag {
RaisinTen marked this conversation as resolved.
Show resolved Hide resolved
public:
static inline void TagNodeContext(v8::Local<v8::Context> context) {
addaleax marked this conversation as resolved.
Show resolved Hide resolved
// Used by ContextEmbedderTag::IsNodeContext to know that we are on a node
// context.
context->SetAlignedPointerInEmbedderData(
ContextEmbedderIndex::kContextTag,
ContextEmbedderTag::kNodeContextTagPtr);
}

static inline bool IsNodeContext(v8::Local<v8::Context> context) {
if (UNLIKELY(context.IsEmpty())) {
return false;
}
if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
ContextEmbedderIndex::kContextTag)) {
return false;
}
if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kContextTag) !=
ContextEmbedderTag::kNodeContextTagPtr)) {
return false;
}
return true;
}

private:
static void* const kNodeContextTagPtr;
static int const kNodeContextTag;

ContextEmbedderTag() = delete;
};

} // namespace node
Expand Down