Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_context_data.h
1 #ifndef SRC_NODE_CONTEXT_DATA_H_ 2 #define SRC_NODE_CONTEXT_DATA_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "util.h" 7 #include "v8.h" 8 9 namespace node { 10 11 // Pick an index that's hopefully out of the way when we're embedded inside 12 // another application. Performance-wise or memory-wise it doesn't matter: 13 // Context::SetAlignedPointerInEmbedderData() is backed by a FixedArray, 14 // worst case we pay a one-time penalty for resizing the array. 15 #ifndef NODE_CONTEXT_EMBEDDER_DATA_INDEX 16 #define NODE_CONTEXT_EMBEDDER_DATA_INDEX 32 17 #endif 18 19 #ifndef NODE_CONTEXT_SANDBOX_OBJECT_INDEX 20 #define NODE_CONTEXT_SANDBOX_OBJECT_INDEX 33 21 #endif 22 23 #ifndef NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX 24 #define NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX 34 25 #endif 26 27 #ifndef NODE_BINDING_DATA_STORE_INDEX 28 #define NODE_BINDING_DATA_STORE_INDEX 35 29 #endif 30 31 #ifndef NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX 32 #define NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX 36 33 #endif 34 35 #ifndef NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX 36 #define NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX 37 37 #endif 38 39 #ifndef NODE_CONTEXT_REALM_INDEX 40 #define NODE_CONTEXT_REALM_INDEX 38 41 #endif 42 43 // NODE_CONTEXT_TAG must be greater than any embedder indexes so that a single 44 // check on the number of embedder data fields can assure the presence of all 45 // embedder indexes. 46 #ifndef NODE_CONTEXT_TAG 47 #define NODE_CONTEXT_TAG 39 48 #endif 49 50 /** 51 * These are indexes used to set Node.js-specific data in the V8 contexts 52 * via v8::Context::SetAlignedPointerInEmbedderData() (for pointers) and 53 * v8::Context::SetEmbedderData() (for v8::Values). 54 * 55 * There are five types of contexts in Node.js: 56 * 1. Default V8 context, with nothing Node.js-specific. This is normally only 57 * created by the embedders that uses v8::Context APIs directly and is not 58 * available through the Node.js JS APIs. Its context snapshot in the 59 * built-in v8 startup snapshot is stored using 60 * v8::SnapshotCreator::SetDefaultContext() - effectively at index 0. 61 * 2. Default Node.js main context. When Node.js is launched typically there is 62 * a main thread on which a main node::Environment is created. The 63 * Environment is associated with its own v8::Isolate (env->isolate()) and a 64 * main v8::Context (env->context()). The corresponding data structure is 65 * node::NodeMainInstance and the Environment is created in 66 * node::NodeMainInstance::Run(). Its context snapshot in the built-in V8 67 * startup snapshot is stored at node::SnapshotData::kNodeMainContextIndex. 68 * 3. Node.js worker context. When a Worker instance is created via 69 * new worker_threads.Worker(), it gets its own OS thread, its 70 * own node::Environment, its own v8::Isolate and its own v8::Context. 71 * The corresponding data structure is node::Worker and the Environment 72 * is created in node::Worker::Run(). 73 * Its context snapshot in the built-in V8 startup snapshot is stored at 74 * node::SnapshotData::kNodeBaseContextIndex. 75 * 4. Contextified vm context: When a contextified context is created via 76 * vm.createContext() or other related vm APIs, the vm.Context instance 77 * gets its own v8::Context. It shares the thread, the v8::Isolate and 78 * the node::Environment with the context where the vm APIs are called. 79 * The corresponding data structure is node::ContextifyContext and 80 * the initialization code is in node::ContextifyContext::New(). 81 * Its context snapshot in the built-in V8 startup snapshot is stored at 82 * node::SnapshotData::kNodeVMContextIndex. 83 * 5. ShadowRealm context: When a JS ShadowRealm is created via new ShadowRealm, 84 * it gets its own v8::Context. It also shares the thread, the v8::Isolate 85 * and the node::Environment with the context where the ShadowRealm 86 * constructor is called. The corresponding data structure is 87 * node::ShadowRealm and the initialization code is in 88 * node::ShadowRealm::New(). 89 */ 90 enum ContextEmbedderIndex { 91 // Pointer to the node::Environment associated with the context. Only set for 92 // context type 2-5. Used by Environment::GetCurrent(context) to retrieve 93 // the node::Environment associated with any Node.js context in the 94 // V8 callbacks. 95 kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX, 96 // A v8::Value which is the sandbox object used to create the contextified vm 97 // context. For example the first argument of vm.createContext(). 98 // Only set for context type 4 and used in ContextifyContext methods. 99 kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX, 100 // A v8::Value indicating whether the context allows WebAssembly code 101 // generation. 102 // Only set for context type 2-5, and for them the default is v8::True. 103 // For context type 4 it's configurable via options.codeGeneration.wasm in the 104 // vm APIs. Used in the default v8::AllowWasmCodeGenerationCallback. 105 kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX, 106 // A v8::Value indicating whether the context allows code generation via 107 // eval() or new Function(). 108 // Only set for context type 2-5, and for them the default is v8::True. 109 // For context type 4 it's configurable via options.codeGeneration.strings in 110 // the 111 // vm APIs. Used in the default v8::AllowCodeGenerationFromStringsCallback. 112 kAllowCodeGenerationFromStrings = 113 NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX, 114 // Pointer to the node::ContextifyContext associated with vm.Contexts. 115 // Only set for context type 4. Used by ContextifyContext::Get() to get 116 // to the ContextifyContext from the property interceptors. 117 kContextifyContext = NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX, 118 // Pointer to the node::Realm associated with the context. 119 // Only set for context type 2-3 and 5. For context type 2-3, it points to a 120 // node::PrincipalRealm. For context type 5 it points to a node::ShadowRealm. 121 // Used by Realm::GetCurrent(context) to retrieve the associated node::Realm 122 // with any Node.js context in the V8 callbacks. 123 kRealm = NODE_CONTEXT_REALM_INDEX, 124 // Pointer to a constant address which is 125 // node::ContextEmbedderTag::kNodeContextTagPtr. 126 // Only set for context type 2-5. Used by ContextEmbedderTag::IsNodeContext() 127 // to check whether a context is a Node.js context. 128 kContextTag = NODE_CONTEXT_TAG, 129 }; 130 131 class ContextEmbedderTag { 132 public: 133 static inline void TagNodeContext(v8::Local<v8::Context> context) { 134 // Used by ContextEmbedderTag::IsNodeContext to know that we are on a node 135 // context. 136 context->SetAlignedPointerInEmbedderData( 137 ContextEmbedderIndex::kContextTag, 138 ContextEmbedderTag::kNodeContextTagPtr); 139 } 140 141 static inline bool IsNodeContext(v8::Local<v8::Context> context) { 142 if (context.IsEmpty()) [[unlikely]] { 143 return false; 144 } 145 if (context->GetNumberOfEmbedderDataFields() <= 146 ContextEmbedderIndex::kContextTag) [[unlikely]] { 147 return false; 148 } 149 if (context->GetAlignedPointerFromEmbedderData( 150 ContextEmbedderIndex::kContextTag) != 151 ContextEmbedderTag::kNodeContextTagPtr) [[unlikely]] { 152 return false; 153 } 154 return true; 155 } 156 157 private: 158 static void* const kNodeContextTagPtr; 159 static int const kNodeContextTag; 160 161 ContextEmbedderTag() = delete; 162 }; 163 164 } // namespace node 165 166 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 167 168 #endif // SRC_NODE_CONTEXT_DATA_H_