Skip to content

Commit

Permalink
src: extract common context embedder tag checks
Browse files Browse the repository at this point in the history
Extract common context embedder tag checks to ContextEmbedderTag so
that verifying if a context is a node context doesn't need to access
private members of node::Environment.

PR-URL: nodejs#44258
Refs: nodejs#44179
Refs: nodejs#44252
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
  • Loading branch information
legendecas authored and Fyko committed Sep 15, 2022
1 parent 82f22ef commit ad692ac
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
11 changes: 1 addition & 10 deletions src/env-inl.h
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 {
public:
static inline void TagNodeContext(v8::Local<v8::Context> context) {
// 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

0 comments on commit ad692ac

Please sign in to comment.