• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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