1 #ifndef SRC_NODE_CONTEXTIFY_H_ 2 #define SRC_NODE_CONTEXTIFY_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "base_object-inl.h" 7 #include "node_context_data.h" 8 #include "node_errors.h" 9 10 namespace node { 11 namespace contextify { 12 13 class MicrotaskQueueWrap : public BaseObject { 14 public: 15 MicrotaskQueueWrap(Environment* env, v8::Local<v8::Object> obj); 16 17 const std::shared_ptr<v8::MicrotaskQueue>& microtask_queue() const; 18 19 static void Init(Environment* env, v8::Local<v8::Object> target); 20 static void New(const v8::FunctionCallbackInfo<v8::Value>& args); 21 22 // This could have methods for running the microtask queue, if we ever decide 23 // to make that fully customizable from userland. 24 25 SET_NO_MEMORY_INFO() 26 SET_MEMORY_INFO_NAME(MicrotaskQueueWrap) 27 SET_SELF_SIZE(MicrotaskQueueWrap) 28 29 private: 30 std::shared_ptr<v8::MicrotaskQueue> microtask_queue_; 31 }; 32 33 struct ContextOptions { 34 v8::Local<v8::String> name; 35 v8::Local<v8::String> origin; 36 v8::Local<v8::Boolean> allow_code_gen_strings; 37 v8::Local<v8::Boolean> allow_code_gen_wasm; 38 BaseObjectPtr<MicrotaskQueueWrap> microtask_queue_wrap; 39 }; 40 41 class ContextifyContext { 42 public: 43 enum InternalFields { kSlot, kInternalFieldCount }; 44 ContextifyContext(Environment* env, 45 v8::Local<v8::Object> sandbox_obj, 46 const ContextOptions& options); 47 ~ContextifyContext(); 48 static void CleanupHook(void* arg); 49 50 v8::MaybeLocal<v8::Object> CreateDataWrapper(Environment* env); 51 v8::MaybeLocal<v8::Context> CreateV8Context(Environment* env, 52 v8::Local<v8::Object> sandbox_obj, 53 const ContextOptions& options); 54 static void Init(Environment* env, v8::Local<v8::Object> target); 55 56 static ContextifyContext* ContextFromContextifiedSandbox( 57 Environment* env, 58 const v8::Local<v8::Object>& sandbox); 59 env()60 inline Environment* env() const { 61 return env_; 62 } 63 context()64 inline v8::Local<v8::Context> context() const { 65 return PersistentToLocal::Default(env()->isolate(), context_); 66 } 67 global_proxy()68 inline v8::Local<v8::Object> global_proxy() const { 69 return context()->Global(); 70 } 71 sandbox()72 inline v8::Local<v8::Object> sandbox() const { 73 return v8::Local<v8::Object>::Cast( 74 context()->GetEmbedderData(ContextEmbedderIndex::kSandboxObject)); 75 } 76 microtask_queue()77 inline std::shared_ptr<v8::MicrotaskQueue> microtask_queue() const { 78 if (!microtask_queue_wrap_) return {}; 79 return microtask_queue_wrap_->microtask_queue(); 80 } 81 82 83 template <typename T> 84 static ContextifyContext* Get(const v8::PropertyCallbackInfo<T>& args); 85 86 private: 87 static void MakeContext(const v8::FunctionCallbackInfo<v8::Value>& args); 88 static void IsContext(const v8::FunctionCallbackInfo<v8::Value>& args); 89 static void CompileFunction( 90 const v8::FunctionCallbackInfo<v8::Value>& args); 91 static void WeakCallback( 92 const v8::WeakCallbackInfo<ContextifyContext>& data); 93 static void PropertyGetterCallback( 94 v8::Local<v8::Name> property, 95 const v8::PropertyCallbackInfo<v8::Value>& args); 96 static void PropertySetterCallback( 97 v8::Local<v8::Name> property, 98 v8::Local<v8::Value> value, 99 const v8::PropertyCallbackInfo<v8::Value>& args); 100 static void PropertyDescriptorCallback( 101 v8::Local<v8::Name> property, 102 const v8::PropertyCallbackInfo<v8::Value>& args); 103 static void PropertyDefinerCallback( 104 v8::Local<v8::Name> property, 105 const v8::PropertyDescriptor& desc, 106 const v8::PropertyCallbackInfo<v8::Value>& args); 107 static void PropertyDeleterCallback( 108 v8::Local<v8::Name> property, 109 const v8::PropertyCallbackInfo<v8::Boolean>& args); 110 static void PropertyEnumeratorCallback( 111 const v8::PropertyCallbackInfo<v8::Array>& args); 112 static void IndexedPropertyGetterCallback( 113 uint32_t index, 114 const v8::PropertyCallbackInfo<v8::Value>& args); 115 static void IndexedPropertySetterCallback( 116 uint32_t index, 117 v8::Local<v8::Value> value, 118 const v8::PropertyCallbackInfo<v8::Value>& args); 119 static void IndexedPropertyDescriptorCallback( 120 uint32_t index, 121 const v8::PropertyCallbackInfo<v8::Value>& args); 122 static void IndexedPropertyDefinerCallback( 123 uint32_t index, 124 const v8::PropertyDescriptor& desc, 125 const v8::PropertyCallbackInfo<v8::Value>& args); 126 static void IndexedPropertyDeleterCallback( 127 uint32_t index, 128 const v8::PropertyCallbackInfo<v8::Boolean>& args); 129 Environment* const env_; 130 v8::Global<v8::Context> context_; 131 BaseObjectPtr<MicrotaskQueueWrap> microtask_queue_wrap_; 132 }; 133 134 class ContextifyScript : public BaseObject { 135 public: 136 SET_NO_MEMORY_INFO() 137 SET_MEMORY_INFO_NAME(ContextifyScript) 138 SET_SELF_SIZE(ContextifyScript) 139 140 ContextifyScript(Environment* env, v8::Local<v8::Object> object); 141 ~ContextifyScript() override; 142 143 static void Init(Environment* env, v8::Local<v8::Object> target); 144 static void New(const v8::FunctionCallbackInfo<v8::Value>& args); 145 static bool InstanceOf(Environment* env, const v8::Local<v8::Value>& args); 146 static void CreateCachedData( 147 const v8::FunctionCallbackInfo<v8::Value>& args); 148 static void RunInThisContext(const v8::FunctionCallbackInfo<v8::Value>& args); 149 static void RunInContext(const v8::FunctionCallbackInfo<v8::Value>& args); 150 static bool EvalMachine(Environment* env, 151 const int64_t timeout, 152 const bool display_errors, 153 const bool break_on_sigint, 154 const bool break_on_first_line, 155 std::shared_ptr<v8::MicrotaskQueue> microtask_queue, 156 const v8::FunctionCallbackInfo<v8::Value>& args); 157 id()158 inline uint32_t id() { return id_; } 159 160 private: 161 v8::Global<v8::UnboundScript> script_; 162 uint32_t id_; 163 }; 164 165 class CompiledFnEntry final : public BaseObject { 166 public: 167 SET_NO_MEMORY_INFO() 168 SET_MEMORY_INFO_NAME(CompiledFnEntry) 169 SET_SELF_SIZE(CompiledFnEntry) 170 171 CompiledFnEntry(Environment* env, 172 v8::Local<v8::Object> object, 173 uint32_t id, 174 v8::Local<v8::ScriptOrModule> script); 175 ~CompiledFnEntry(); 176 IsNotIndicativeOfMemoryLeakAtExit()177 bool IsNotIndicativeOfMemoryLeakAtExit() const override { return true; } 178 179 private: 180 uint32_t id_; 181 v8::Global<v8::ScriptOrModule> script_; 182 183 static void WeakCallback(const v8::WeakCallbackInfo<CompiledFnEntry>& data); 184 }; 185 186 } // namespace contextify 187 } // namespace node 188 189 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 190 191 #endif // SRC_NODE_CONTEXTIFY_H_ 192